j3w1 / theme

j3w1 / theme4.0.0

j3w1 / command

  • SPEC Overview
  • SPEC Foundations
  • SPEC Components
  • SPEC Patterns
  • SPEC Tokens
  • SPEC Tools
  • SPEC Workbench
  • SPEC Form builder
  • SPEC Task kit
  • SPEC Recipes
  • SPEC Figma bridge
  • SPEC Report an issue
  • SPEC Implement
  • SPEC For agents
  • SPEC Ports
  • SPEC Releases
  • SPEC Specification
  • DEMO Vue application demo

Diagnostics

Inline problem markers in code (underline patterns, an error line and an overview stripe) and the problems panel that lists them as a listbox, each severity carrying its glyph.

stable · light DOM · 4.0.0. Light DOM retains static content, native semantics, label relationships and host composition without duplicating controls.

Live variants

inline

✕ Language server stopped; markers may be stale.

import { readFile } from "node:fs/promises";
const title = document.title;
function render(frame) {
  const count = frame.children.length;
  escape(title);
  return frmae.title + count;
}
render(document.body) == null;

No problems in title.js

Markup
<j3w1-diagnostics id="example-diagnostics-inline"><div class="diagnostics diagnostics-inline">
  <p class="diagnostics-status" role="status">✕ Language server stopped; markers may be stale.</p>
  <div class="diagnostics-box" role="textbox" aria-multiline="true" aria-readonly="true" aria-label="title.js with 6 diagnostics, read-only" tabindex="0">
    <pre class="diagnostics-code"><span class="diagnostics-line"><span class="diagnostics-ln" aria-hidden="true">1</span><span class="diagnostics-text">import { <span class="diagnostics-unused" title="readFile is declared but never used">readFile</span> } from "node:fs/promises";</span><span class="diagnostics-mark diagnostics-mark-hint" aria-hidden="true">·</span></span>
<span class="diagnostics-line"><span class="diagnostics-ln" aria-hidden="true">2</span><span class="diagnostics-text">const title = document.title;</span><span class="diagnostics-mark" aria-hidden="true"></span></span>
<span class="diagnostics-line"><span class="diagnostics-ln" aria-hidden="true">3</span><span class="diagnostics-text">function <span class="diagnostics-hint" title="Hint: render could be an arrow function">render</span>(frame) {</span><span class="diagnostics-mark diagnostics-mark-hint" aria-hidden="true">·</span></span>
<span class="diagnostics-line"><span class="diagnostics-ln" aria-hidden="true">4</span><span class="diagnostics-text">  const count = <span class="diagnostics-info" title="Info: frame.children may be undefined; consider ?.">frame.children</span>.length;</span><span class="diagnostics-mark diagnostics-mark-info" aria-hidden="true">i</span></span>
<span class="diagnostics-line"><span class="diagnostics-ln" aria-hidden="true">5</span><span class="diagnostics-text">  <span class="diagnostics-deprecated" title="escape() is deprecated">escape</span>(title);</span><span class="diagnostics-mark diagnostics-mark-hint" aria-hidden="true">·</span></span>
<span class="diagnostics-line diagnostics-line-error"><span class="diagnostics-ln" aria-hidden="true">6</span><span class="diagnostics-text">  return <span class="diagnostics-error" title="Error: frmae is not defined">frmae</span>.title + count;</span><span class="diagnostics-mark diagnostics-mark-error" aria-hidden="true">✕</span></span>
<span class="diagnostics-line"><span class="diagnostics-ln" aria-hidden="true">7</span><span class="diagnostics-text">}</span><span class="diagnostics-mark" aria-hidden="true"></span></span>
<span class="diagnostics-line"><span class="diagnostics-ln" aria-hidden="true">8</span><span class="diagnostics-text">render(document.body) <span class="diagnostics-warning diagnostics-target" title="Warning: expected === and instead saw ==">==</span> null;</span><span class="diagnostics-mark diagnostics-mark-warning" aria-hidden="true">!</span></span></pre>
  </div>
  <p class="diagnostics-empty"><span class="diagnostics-glyph diagnostics-glyph-success" aria-hidden="true">✓</span> No problems in title.js</p>
</div></j3w1-diagnostics>

panel

Problems ✕ 1 error ! 1 warning i 1 info · 3 hints

✕ Language server stopped; the list may be stale.

  • Error: frmae is not defined title.js:6:10 no-undef
  • Warning: Expected === and instead saw == title.js:8:23 eqeqeq
  • Info: frame.children may be undefined; consider optional chaining title.js:4:17 ts-2532
  • Hint: readFile is declared but never used title.js:1:10 no-unused-vars
  • Hint: escape() is deprecated; use encodeURIComponent() title.js:5:3 deprecation

No problems

Markup
<j3w1-diagnostics id="example-diagnostics-panel"><div class="diagnostics diagnostics-panel">
  <div class="diagnostics-header">
    <span class="diagnostics-title" id="example-diagnostics-panel-dg-title">Problems</span>
    <span class="diagnostics-count"><span class="diagnostics-glyph diagnostics-glyph-error">✕</span> 1 <span class="sr-only">error</span></span>
    <span class="diagnostics-count"><span class="diagnostics-glyph diagnostics-glyph-warning">!</span> 1 <span class="sr-only">warning</span></span>
    <span class="diagnostics-count"><span class="diagnostics-glyph diagnostics-glyph-info">i</span> 1 <span class="sr-only">info</span></span>
    <span class="diagnostics-count"><span class="diagnostics-glyph diagnostics-glyph-hint">·</span> 3 <span class="sr-only">hints</span></span>
  </div>
  <p class="diagnostics-status" role="status">✕ Language server stopped; the list may be stale.</p>
  <ul class="diagnostics-list" role="listbox" aria-labelledby="example-diagnostics-panel-dg-title" aria-activedescendant="example-diagnostics-panel-dg-row-2" tabindex="0">
    <li class="diagnostics-row" role="option" id="example-diagnostics-panel-dg-row-1" aria-selected="false">
      <span class="diagnostics-glyph diagnostics-glyph-error" aria-hidden="true">✕</span>
      <span class="diagnostics-message"><span class="sr-only">Error: </span>frmae is not defined</span>
      <span class="diagnostics-loc">title.js:6:10</span>
      <span class="diagnostics-rule">no-undef</span>
    </li>
    <li class="diagnostics-row diagnostics-row-active" role="option" id="example-diagnostics-panel-dg-row-2" aria-selected="false">
      <span class="diagnostics-glyph diagnostics-glyph-warning" aria-hidden="true">!</span>
      <span class="diagnostics-message"><span class="sr-only">Warning: </span>Expected === and instead saw ==</span>
      <span class="diagnostics-loc">title.js:8:23</span>
      <span class="diagnostics-rule">eqeqeq</span>
    </li>
    <li class="diagnostics-row" role="option" id="example-diagnostics-panel-dg-row-3" aria-selected="false">
      <span class="diagnostics-glyph diagnostics-glyph-info" aria-hidden="true">i</span>
      <span class="diagnostics-message"><span class="sr-only">Info: </span>frame.children may be undefined; consider optional chaining</span>
      <span class="diagnostics-loc">title.js:4:17</span>
      <span class="diagnostics-rule">ts-2532</span>
    </li>
    <li class="diagnostics-row" role="option" id="example-diagnostics-panel-dg-row-4" aria-selected="false">
      <span class="diagnostics-glyph diagnostics-glyph-hint" aria-hidden="true">·</span>
      <span class="diagnostics-message"><span class="sr-only">Hint: </span>readFile is declared but never used</span>
      <span class="diagnostics-loc">title.js:1:10</span>
      <span class="diagnostics-rule">no-unused-vars</span>
    </li>
    <li class="diagnostics-row" role="option" id="example-diagnostics-panel-dg-row-5" aria-selected="false">
      <span class="diagnostics-glyph diagnostics-glyph-hint" aria-hidden="true">·</span>
      <span class="diagnostics-message"><span class="sr-only">Hint: </span>escape() is deprecated; use encodeURIComponent()</span>
      <span class="diagnostics-loc">title.js:5:3</span>
      <span class="diagnostics-rule">deprecation</span>
    </li>
  </ul>
  <p class="diagnostics-empty"><span class="diagnostics-glyph diagnostics-glyph-success" aria-hidden="true">✓</span> No problems</p>
</div></j3w1-diagnostics>

Install and register

Use the exact version. If npm publication is pending, install the release tarball from the installation guide.

npm install --save-exact @j3w1/ui@4.0.0
import '@j3w1/ui/tokens.css';
import '@j3w1/ui/styles/diagnostics.css';
import '@j3w1/ui/register/diagnostics';

Insert the maintained markup above after loading these imports. Its native children provide accessible names and form behavior; the empty custom tag alone does not create a control.

Vue SFC, React, Astro and plain HTML integration →

Copy the complete implementation

npx --package=@j3w1/ui@4.0.0 j3w1-ui copy diagnostics --out ./vendor/j3w1/diagnostics

The CLI verifies every file before writing and refuses overwrites. Serve the output over HTTP and open index.html. Keep its modules, CSS, tokens and licence notices together.

Public API

attributes

NameType / signatureMeaning
disabledCustomEventDisable the native controls owned by this instance.
loadingCustomEventMark the primary control busy and prevent duplicate activation.

properties

NameType / signatureMeaning
disabledbooleanDelegates disabled state to native children.
namestringNative control name; application form keys remain explicit.

methods

NameType / signatureMeaning
refresh(): voidReconnect behavior after replacing native child structure.
focus(options?: FocusOptions): voidFocus the first usable native control.
setText(text: string): voidReplace the bounded read-only text view; no code or shell execution occurs.

events

NameType / signatureMeaning
j3w1-actionCustomEventRequest a developer-view action; editing and execution belong to the host.

Dependencies and verification

Registered components: none. Style dependencies: none.

Package presence establishes an available implementation. Actual passes depend on the tested artifact and environment. Read specification execution evidence; read packed-consumer evidence; inspect the complete state matrix.

Full implementation manifest, API and token dependency closure

Canonical specification

Diagnostics diagnostics

  • Family: Developer interfaces
  • Maturity: stable
  • Priority: R1
  • Since: 0.1.0
  • Custom widget: inline: decorated spans inside a read-only textbox presentation; panel: APG listbox with aria-activedescendant — APG pattern
  • specified
  • demonstrated

Inline problem markers in code (underline patterns, an error line and an overview stripe) and the problems panel that lists them as a listbox, each severity carrying its glyph.

Report an issue with this component

Tokens

Focus a role to inspect its values; follow its link for persistent usage and source details.

PartRoleValueUse
root.bgcolor.surface.defaultapproveduse#0d0707D-041 surface.default: color.primitive.modern.panel.
root.bordercolor.border.controlapproveduse#c81a1aD-041 owner correction: red control and floating-frame borders, distinct from rose text.
code.bgcolor.code.bgapproveduse#000000D-041 code.bg: color.primitive.ink.0.
code.textcolor.text.defaultapproveduse#e99499D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
code.line-numbercolor.code.line-numberapproveduse#bd787dD-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
code.gutter-rulecolor.code.gutter-ruleapproveduse#482b2bD-041 code.gutter-rule: color.primitive.modern.divider.
code.selection-bgcolor.code.selection-bgobserveduse#420f0cEditor selection background (muted text stays 4.71:1).
error.underlinecolor.diagnostic.error.underlineobserveduse#e53935Error wavy underline.
error.textcolor.diagnostic.error.textobserveduse#f73f35Error message text.
error.stripecolor.diagnostic.error.stripeobserveduse#e53935Error stripe mark.
error.line-bgcolor.diagnostic.error.bgobserveduse#2b0e0dError line background.
warning.underlinecolor.diagnostic.warning.underlineapproveduse#e5c07bD-041 diagnostic.warning.underline: color.primitive.modern.amber.
warning.textcolor.diagnostic.warning.textapproveduse#e5c07bD-041 diagnostic.warning.text: color.primitive.modern.amber.
warning.stripecolor.diagnostic.warning.stripeapproveduse#e5c07bD-041 diagnostic.warning.stripe: color.primitive.modern.amber.
info.underlinecolor.diagnostic.info.underlineapproveduse#82b4ffD-041 diagnostic.info.underline: color.primitive.modern.blue.
info.textcolor.diagnostic.info.textapproveduse#82b4ffD-041 diagnostic.info.text: color.primitive.modern.blue.
hint.underlinecolor.diagnostic.hint.underlineapproveduse#bd787dD-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
hint.textcolor.text.subtleapproveduse#bd787dD-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
unused.textcolor.diagnostic.unused.textapproveduse#d4868bD-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
deprecated.textcolor.code.syntax.deprecatedapproveduse#bd787dD-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
row.textcolor.text.defaultapproveduse#e99499D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
row.locationcolor.text.mutedapproveduse#d4868bD-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
row.dividercolor.border.dividerapproveduse#482b2bD-041 border.divider: color.primitive.modern.divider.
row.bg-hovercolor.interaction.hover.bgapproveduse#1c1010D-041 interaction.hover.bg: color.primitive.modern.hover.
row.ringcolor.interaction.focus.ringobserveduse#e539351px dashed focus ring on controls and rows.
row.bg-selectedcolor.interaction.selection.bgapproveduse#531310Selected row, tab, workspace; D-027 recessed the fill, leaving the 2px indicator and the check to carry selection.
row.text-selectedcolor.interaction.selection.textobserveduse#f4eeeeText on the selection.
row.ring-selectedcolor.interaction.focus.ringobserveduse#e539351px dashed focus ring on controls and rows.
header.textcolor.text.brightapproveduse#ffa2a7D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
status.textcolor.status.danger.textobserveduse#f07178D-041 readable error text on neutral surfaces and native warning tints.
empty.textcolor.text.mutedapproveduse#d4868bD-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
empty.glyphcolor.status.success.textapproveduse#82d9a0D-041 status.success.text: color.primitive.modern.green.

State matrix

Every declared state and combination, statically rendered; the default cell is live. Sizes: compact, comfortable (switch with the density control above).

StateInline markersProblems panel
default

✕ Language server stopped; markers may be stale.

import { readFile } from "node:fs/promises";
const title = document.title;
function render(frame) {
  const count = frame.children.length;
  escape(title);
  return frmae.title + count;
}
render(document.body) == null;

No problems in title.js

Problems ✕ 1 error ! 1 warning i 1 info · 3 hints

✕ Language server stopped; the list may be stale.

  • Error: frmae is not defined title.js:6:10 no-undef
  • Warning: Expected === and instead saw == title.js:8:23 eqeqeq
  • Info: frame.children may be undefined; consider optional chaining title.js:4:17 ts-2532
  • Hint: readFile is declared but never used title.js:1:10 no-unused-vars
  • Hint: escape() is deprecated; use encodeURIComponent() title.js:5:3 deprecation

No problems

hover
focus-visible
selected
selected+focus-visible
error
empty

Purpose

How problems appear on code and in the list that indexes them. Six kinds, each told apart by pattern and glyph as well as colour. The panel is the keyboard route to every marker.

Anatomy

Root .diagnostics with .diagnostics-inline or .diagnostics-panel. Inline: .diagnostics-code (the <pre>), -line, -ln, -text, -mark (the stripe cell) and the ranges .diagnostics-error, -warning, -info, -hint, -unused, -deprecated; .diagnostics-line-error is the filled row; .diagnostics-target is the range of the selected row. Panel: -header, -title, -count, -status, -list, -row, -glyph (with -glyph-error and so on), -message, -loc, -rule, -empty. Patterns: error and warning wavy, info and hint dotted, unused dotted in color.diagnostic.unused.text, deprecated line-through in color.code.syntax.deprecated. Glyphs: ✕ error in color.diagnostic.error.text, ! warning in color.diagnostic.warning.text, i info in color.diagnostic.info.text, · hint in color.text.subtle. The stripe mark repeats the glyph in the stripe colour (color.diagnostic.error.stripe, color.diagnostic.warning.stripe).

States

StateVisualNon-colour channel
defaultranges decorated on color.code.bg; the error row filled color.diagnostic.error.bg; panel rows on color.surface.default, 1px color.border.divider betweenunderline pattern; glyph
hoverpanel row → color.interaction.hover.bg; inline ranges unchanged (the hover tooltip is a host surface)cursor: default on rows
focus-visibleactive row: 1px dashed color.interaction.focus.ring at −2px; inline box: 2px color.interaction.focus.ring-container at −3pxthe ring
selectedrow filled color.interaction.selection.bg, text and glyph color.interaction.selection.text; the matching inline range filled color.code.selection-bg under its underlinearia-selected; the glyph stays; the fill spans the row
selected+focus-visiblethe selection fill and 1px dashed color.interaction.focus.ring at −2pxboth at once
errorprovider failed: a role=status line with ✕ in color.status.danger.text above the stale rows; the stripe shows the same ✕ at its topglyph; live announcement
emptyrows, stripe marks and inline decorations removed; ✓ No problems in color.text.muted, glyph in color.status.success.textglyph; the absence of decoration

Precedence: selected > hover; focus-visible is drawn on top. A selected row recolours its glyph to the on-selection text, so the shape, not the hue, carries the severity.

Keyboard

As in the key table; next and previous problem and the hover card belong to the host.

Accessibility

Never colour-only: the underline pattern in code, the glyph in the panel, and the glyph is part of the option’s accessible name (“Error: frmae is not defined, title.js line 6”). The error row fill adds to the wavy underline, never replaces it. Text, including unused code, meets 4.5:1; every underline meets 3:1 on its actual background, the selected range included. The status line is announced once. In forced-colours mode the patterns persist because they are text-decoration, not backgrounds.

Portability

Where wavy is unavailable the port uses a plain underline plus the glyph and records the deviation. Hosts with their own overview ruler map the stripe colours; hosts without one omit the stripe and keep the glyphs.

Non-examples

Red-only errors without ✕ or the wavy pattern. Wavy for every severity. Purple or cyan for info and hint. A row hover that changes only text colour. A selected row whose glyph keeps its severity colour on the fill. A rounded highlight or left accent bar instead of the row fill. Removing the error line fill to “calm” the editor.

Contrast report

32 declared pairs measured on resolved sRGB values with the WCAG 2.x formula; 0 waived (decorative only), 0 failing. A pass is a design target for the named role, not an application-wide conformance claim.

PairStateKindForegroundBackgroundRatioMinResult
diagnostics default textdefaulttextcolor.text.default #e99499color.surface.default #0d07078.724.5pass
diagnostics default borderdefaultuicolor.border.control #c81a1acolor.surface.default #0d07073.443pass
diagnostics hover texthovertextcolor.text.default #e99499color.interaction.hover.bg #1c10108.104.5pass
diagnostics focus-visible textfocus-visibletextcolor.text.default #e99499color.surface.default #0d07078.724.5pass
diagnostics focus-visible outlinefocus-visibleuicolor.interaction.focus.ring #e53935color.surface.default #0d07074.733pass
diagnostics selected textselectedtextcolor.interaction.selection.text #f4eeeecolor.interaction.selection.bg #53131012.474.5pass
diagnostics selected+focus-visible textselected+focus-visibletextcolor.interaction.selection.text #f4eeeecolor.interaction.selection.bg #53131012.474.5pass
diagnostics selected+focus-visible outlineselected+focus-visibleuicolor.interaction.focus.ring #e53935color.interaction.selection.bg #5313103.383pass
diagnostics error texterrortextcolor.status.danger.text #f07178color.surface.default #0d07076.984.5pass
diagnostics empty textemptytextcolor.text.muted #d4868bcolor.surface.default #0d07077.224.5pass
code text—textcolor.text.default #e99499color.code.bg #0000009.164.5pass
code text on the error line—textcolor.text.default #e99499color.diagnostic.error.bg #2b0e0d7.824.5pass
error glyph on the error line—textcolor.diagnostic.error.text #f73f35color.diagnostic.error.bg #2b0e0d4.884.5pass
error underline—uicolor.diagnostic.error.underline #e53935color.code.bg #0000004.973pass
error underline on the error line—uicolor.diagnostic.error.underline #e53935color.diagnostic.error.bg #2b0e0d4.243pass
warning underline inside the selected rangeselecteduicolor.diagnostic.warning.underline #e5c07bcolor.code.selection-bg #420f0c9.313pass
warning underline—uicolor.diagnostic.warning.underline #e5c07bcolor.code.bg #00000012.163pass
info underline—uicolor.diagnostic.info.underline #82b4ffcolor.code.bg #0000009.923pass
hint underline—uicolor.diagnostic.hint.underline #bd787dcolor.code.bg #0000006.153pass
unused text—textcolor.diagnostic.unused.text #d4868bcolor.code.bg #0000007.584.5pass
deprecated text—textcolor.code.syntax.deprecated #bd787dcolor.code.bg #0000006.154.5pass
error stripe mark—uicolor.diagnostic.error.stripe #e53935color.code.bg #0000004.973pass
warning stripe mark—uicolor.diagnostic.warning.stripe #e5c07bcolor.code.bg #00000012.163pass
info stripe mark—uicolor.diagnostic.info.text #82b4ffcolor.code.bg #0000009.923pass
error glyph and count in the panel—textcolor.diagnostic.error.text #f73f35color.surface.default #0d07075.444.5pass
warning glyph and count in the panel—textcolor.diagnostic.warning.text #e5c07bcolor.surface.default #0d070711.574.5pass
info glyph and count in the panel—textcolor.diagnostic.info.text #82b4ffcolor.surface.default #0d07079.444.5pass
hint glyph in the panel—textcolor.text.subtle #bd787dcolor.surface.default #0d07075.854.5pass
location and rule code—textcolor.text.muted #d4868bcolor.surface.default #0d07077.224.5pass
row text on hoverhovertextcolor.text.default #e99499color.interaction.hover.bg #1c10108.104.5pass
error glyph on hoverhovertextcolor.diagnostic.error.text #f73f35color.interaction.hover.bg #1c10105.064.5pass
the ✓ of the empty messageemptytextcolor.status.success.text #82d9a0color.surface.default #0d070711.794.5pass

Keys

KeyAction
Tab / Shift+TabMoves focus to and from the list as one stop; the active row is restored.
Down / UpMoves the active row; selection follows focus in this single-select listbox.
Home / EndFirst or last row.
EnterOpens the location in the editor and moves focus there.
Type-aheadJumps to the next row whose message starts with the typed characters.
(host)Inline markers have no keyboard of their own; navigation between problems (F8-style) is the host's binding.

For agents

Component JSON ·Implementation brief ·Build a task kit ·

Related: code-editor diff-view terminal

Stress fixtures: FX-STATE-MATRIX FX-320 FX-ZOOM-200 FX-RM FX-HC FX-LONG FX-I18N