Skip to content

Typography contract misses classes supplied through openMenu options #498

Description

@BorisTyshkevich

Problem

The typography contract test is intended to catch UI elements that render text without any matching CSS rule. Today it only scans source files for literal hyperscript attributes shaped like:

class: 'some-class'

using:

/class:\s*'([^']+)'/g

openMenu() consumers supply their component-specific classes through different properties:

openMenu({
  menuClass: 'qtab-close-confirm',
  rows: [
    { kind: 'item', extraClass: 'qtab-close-confirm-go', ... },
    { kind: 'item', extraClass: 'qtab-close-confirm-cancel', ... },
  ],
});

openMenu() later appends these values to the real DOM class attribute, but the contract scanner never sees them because menuClass and extraClass do not match its regex.

Impact

This is a regression-detection gap, not a currently broken UI.

Known menu classes such as the query-tab close confirmation and Dashboard-tree delete confirmation already have CSS. Also, openMenu() always applies generic .file-menu, .fm-item, and .fm-section styling, so a missing consumer-specific rule would not produce a completely unstyled browser-default dialog.

However, the test would fail to catch missing presentation that communicates the menu's specific purpose, for example:

  • confirmation-menu width or layout;
  • destructive-action colour and emphasis;
  • muted Cancel styling;
  • component-specific spacing or state treatment.

A future menu could therefore remain functional but ship visually inconsistent or misleading while the typography contract still passes.

Suggested fix

Add a focused assertion for literal classes supplied through openMenu options.

Scan src/ui/**/*.ts for literal values assigned to menuClass and extraClass, split whitespace-separated class groups, and assert that each class appears in src/styles.css.

A simple extraction pattern is sufficient for the current API:

/\b(?:menuClass|extraClass):\s*'([^']+)'/g

Keeping this as a separate openMenu extension classes have CSS rules test is clearer than silently broadening the existing generic class: scanner. It should scan all UI source files rather than extending the existing curated file list, so new menu consumers are covered automatically.

Adding src/ui/menu.ts itself to the current list is not enough: that file only contains template literals which interpolate class values supplied by callers.

Acceptance criteria

  • Literal menuClass values in UI source files are checked against the stylesheet.
  • Literal extraClass values in UI source files are checked against the stylesheet.
  • Multiple classes in one option value are handled.
  • A fixture or focused test proves that removing one such CSS rule fails the contract.
  • Existing generic .file-menu / .fm-item classes remain covered by the current scanner.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinglowlow priority

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions