Give a hand-typed header its own box #29

Closed
opened 2026-08-25 14:56:11 +00:00 by jcoffey-dev · 0 comments
Owner

Fixes #23.

Picking "Other header…" replaced the comparator instead of sitting beside it. .rule-row is a three-column grid — field, comparator, value — and RuleDialog rendered the header-name box into the comparator's column, so the comparator disappeared. The rule kept whatever it had been at the moment of switching (contains, set by the field dropdown's own handler), with no way to change it: matching a header is exactly, or on a regex with matches, could not be expressed at all.

The header name now gets a column of its own, on a row that widens to hold it (.rule-row.named-header), and the comparator keeps its own. Nothing changes for the listed headers, address, size, body or true rows.

The header-name box also gained an aria-label — it only had a placeholder, so it was unnamed for a screen reader.

Not addressed: the row doesn't reflow on a narrow screen, so four content columns are tighter than three. That is true of .rule-row generally today — there is no breakpoint for it at all — so it seemed better left to a change that handles the whole row than half-done here.

Tested: npm run typecheck, npm test (183 web + 88 server, all passing), with a new RuleDialog render test that picks "Other header…" and asserts the comparator is still there, still lists matches, and still changes. Confirmed it fails against the old markup.

🤖 Generated with Claude Code

Merged 2026-08-25 as coffey-labs/ihasmail@0cbebed645

Rebuilt from: git history, session transcript.

Fixes #23. Picking "Other header…" replaced the comparator instead of sitting beside it. `.rule-row` is a three-column grid — field, comparator, value — and `RuleDialog` rendered the header-name box into the comparator's column, so the comparator disappeared. The rule kept whatever it had been at the moment of switching (`contains`, set by the field dropdown's own handler), with no way to change it: matching a header `is` exactly, or on a regex with `matches`, could not be expressed at all. The header name now gets a column of its own, on a row that widens to hold it (`.rule-row.named-header`), and the comparator keeps its own. Nothing changes for the listed headers, `address`, `size`, `body` or `true` rows. The header-name box also gained an `aria-label` — it only had a placeholder, so it was unnamed for a screen reader. Not addressed: the row doesn't reflow on a narrow screen, so four content columns are tighter than three. That is true of `.rule-row` generally today — there is no breakpoint for it at all — so it seemed better left to a change that handles the whole row than half-done here. Tested: `npm run typecheck`, `npm test` (183 web + 88 server, all passing), with a new `RuleDialog` render test that picks "Other header…" and asserts the comparator is still there, still lists `matches`, and still changes. Confirmed it fails against the old markup. 🤖 Generated with [Claude Code](https://claude.com/claude-code) **Merged** 2026-08-25 as coffey-labs/ihasmail@0cbebed64555 <sub>Rebuilt from: git history, session transcript.</sub>
This repo is archived. You cannot comment on issues.