@micha.bigler/ui-core-micha 2.33.2 → 2.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/WORK_ORDERS.md +9 -2
- package/dist/auth/ReauthModal.js +3 -1
- package/dist/components/AccessCodeManager.js +16 -14
- package/dist/components/AccessCodeSingleUseToggle.js +2 -1
- package/dist/components/AllowedEmailDomainsManager.js +3 -1
- package/dist/components/AuthFactorRequirementCard.js +2 -1
- package/dist/components/BulkInviteCsvTab.js +7 -7
- package/dist/components/LoginForm.js +2 -1
- package/dist/components/MFAComponent.js +15 -8
- package/dist/components/MfaLoginComponent.js +4 -1
- package/dist/components/PasskeysComponent.js +4 -2
- package/dist/components/QrSignupManager.js +2 -1
- package/dist/components/QrSignupValidityManager.js +4 -1
- package/dist/components/RegistrationMethodsManager.js +3 -1
- package/dist/components/SecurityComponent.js +3 -1
- package/dist/components/SocialLoginButtons.js +2 -1
- package/dist/components/SupportRecoveryRequestsTab.js +4 -1
- package/dist/components/UserInviteComponent.js +8 -8
- package/dist/components/UserListComponent.js +8 -4
- package/dist/components/charts/ChartFrame.js +8 -3
- package/dist/components/charts/TimeSeriesChart.js +7 -4
- package/dist/components/charts/exportChart.js +2 -2
- package/dist/index.js +1 -1
- package/dist/layout/PageLayout.js +3 -2
- package/dist/messaging/AttachmentList.js +6 -1
- package/dist/messaging/Composer.js +2 -1
- package/dist/messaging/DirectMessageLauncher.js +2 -1
- package/dist/messaging/MessageBubble.js +29 -8
- package/dist/messaging/PollCard.js +6 -4
- package/dist/messaging/Thread.js +2 -1
- package/dist/notifications/NotificationSettings.js +17 -3
- package/dist/notifications/PopupSurface.js +2 -1
- package/dist/onboarding/steps/BrowserPushStep.js +2 -1
- package/dist/pages/AccountPage.js +2 -1
- package/dist/pages/LoginPage.js +2 -1
- package/dist/pages/SignUpPage.js +2 -1
- package/dist/pages/SignupConfirmPage.js +2 -1
- package/dist/theme/index.js +2 -1
- package/dist/theme/kitSxRegistry.js +187 -0
- package/dist/theme/themeCompleteness.js +422 -1
- package/package.json +1 -1
- package/src/auth/ReauthModal.jsx +5 -2
- package/src/components/AccessCodeManager.jsx +22 -20
- package/src/components/AccessCodeSingleUseToggle.jsx +4 -2
- package/src/components/AllowedEmailDomainsManager.jsx +6 -3
- package/src/components/AuthFactorRequirementCard.jsx +4 -2
- package/src/components/BulkInviteCsvTab.jsx +11 -10
- package/src/components/LoginForm.jsx +5 -3
- package/src/components/MFAComponent.jsx +20 -12
- package/src/components/MfaLoginComponent.jsx +9 -5
- package/src/components/PasskeysComponent.jsx +7 -4
- package/src/components/QrSignupManager.jsx +6 -4
- package/src/components/QrSignupValidityManager.jsx +8 -4
- package/src/components/RegistrationMethodsManager.jsx +7 -4
- package/src/components/SecurityComponent.jsx +10 -7
- package/src/components/SocialLoginButtons.jsx +2 -1
- package/src/components/SupportRecoveryRequestsTab.jsx +8 -4
- package/src/components/UserInviteComponent.jsx +10 -10
- package/src/components/UserListComponent.jsx +12 -7
- package/src/components/charts/ChartFrame.jsx +13 -3
- package/src/components/charts/TimeSeriesChart.jsx +8 -4
- package/src/components/charts/exportChart.js +2 -2
- package/src/index.js +4 -0
- package/src/layout/PageLayout.jsx +4 -2
- package/src/messaging/AttachmentList.jsx +9 -3
- package/src/messaging/Composer.jsx +3 -1
- package/src/messaging/DirectMessageLauncher.jsx +3 -1
- package/src/messaging/MessageBubble.jsx +31 -9
- package/src/messaging/PollCard.jsx +8 -6
- package/src/messaging/Thread.jsx +3 -1
- package/src/notifications/NotificationSettings.jsx +24 -9
- package/src/notifications/PopupSurface.jsx +3 -1
- package/src/onboarding/steps/BrowserPushStep.jsx +3 -1
- package/src/pages/AccountPage.jsx +11 -9
- package/src/pages/LoginPage.jsx +6 -4
- package/src/pages/SignUpPage.jsx +4 -2
- package/src/pages/SignupConfirmPage.jsx +4 -2
- package/src/theme/index.js +4 -0
- package/src/theme/kitSxRegistry.js +246 -0
- package/src/theme/themeCompleteness.js +451 -1
- package/tests/ChartFrame.test.jsx +5 -0
- package/tests/themeCompleteness.test.js +351 -0
- package/work-orders/THEME-4.md +86 -0
- package/work-orders/THEME-5.md +341 -0
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
# THEME-5 — Hold the kit to its own baseline
|
|
2
|
+
|
|
3
|
+
**Target repo:** `ui-core-micha` (branch `main` — this repo has no `develop`)
|
|
4
|
+
**Tier:** 3 (shared core)
|
|
5
|
+
**Review:** independent `reviewer` **and** `ui_reviewer` — both mandatory, concurrent. `ui_reviewer`
|
|
6
|
+
applies because rendered colours change in a screen **ten apps mount**; see "Blast radius".
|
|
7
|
+
**Version target:** the next **minor** after `THEME-4` — a new exported check is additive API. Read the
|
|
8
|
+
published version at implementation time; do **not** hardcode a number from this file.
|
|
9
|
+
**Strand:** `DS-18` follow-ups, both named in `THEME-4`'s landing notes
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## A. Envelope
|
|
14
|
+
|
|
15
|
+
### Goal
|
|
16
|
+
|
|
17
|
+
Two gaps left open by `THEME-4`, and they belong together because both are the same embarrassment:
|
|
18
|
+
**the kit is not fully on the baseline it exists to enforce.**
|
|
19
|
+
|
|
20
|
+
1. `THEME-4`'s shadowing check normalises **spacing** shorthands only. Other MUI `sx` aliases —
|
|
21
|
+
`bgcolor` above all — still compare as raw strings and would miss a collision.
|
|
22
|
+
2. The kit carries **off-palette colour values**. No app palette reaches them.
|
|
23
|
+
|
|
24
|
+
### Part 1 — finish the alias normalisation
|
|
25
|
+
|
|
26
|
+
`SPACING_SHORTHAND_LONGHANDS` (`src/theme/themeCompleteness.js:383`) covers `p*` and `m*`. Extend the
|
|
27
|
+
map to every MUI `sx` alias that can land on a property the baseline sets — `bgcolor` →
|
|
28
|
+
`backgroundColor` is the one with a real near-term risk.
|
|
29
|
+
|
|
30
|
+
**Verified state, so nobody hunts for a bug that is not there yet:** `MFA_ACTIVE_CARD_SX =
|
|
31
|
+
{ bgcolor: '#f0fdf4' }` is registered against `MuiCard` (`kitSxRegistry.js:190`), and the baseline
|
|
32
|
+
sets `borderRadius`, `boxShadow` and `borderColor` on `MuiCard` — **not** `backgroundColor`. So there
|
|
33
|
+
is **no live collision today**. This is a latent gap whose trigger is near: `THEME-3` has just shown
|
|
34
|
+
the surface-token set still grows, and the day a `backgroundColor` default lands on `Paper` or `Card`
|
|
35
|
+
the miss becomes silent.
|
|
36
|
+
|
|
37
|
+
**Write the bound as an open one.** `THEME-4`'s WO named its own limits as a list — nested and
|
|
38
|
+
conditional `sx` — and the first real miss was something not on that list (alias spelling). Say
|
|
39
|
+
"unknown normalisation gaps remain" rather than enumerating, because an enumeration reads as
|
|
40
|
+
completeness.
|
|
41
|
+
|
|
42
|
+
### Part 2 — an off-palette colour scan, and fix what it finds
|
|
43
|
+
|
|
44
|
+
A new exported check, same finding contract as the others (`{ findings: [{ surface, reason }] }`),
|
|
45
|
+
scanning `src/**` for colour values that are not baseline tokens. Wire it as a hard failure in ucm's
|
|
46
|
+
own suite.
|
|
47
|
+
|
|
48
|
+
**Three classes, and a hex-only scan catches just the first:**
|
|
49
|
+
|
|
50
|
+
| Class | Example | In scope |
|
|
51
|
+
|---|---|---|
|
|
52
|
+
| Hex literal | `bgcolor: '#f5f5f5'` | **yes** |
|
|
53
|
+
| Named CSS colour | `bgcolor: 'white'` (`MFAComponent.jsx:231`) | **yes** — same defect, invisible to a hex scan |
|
|
54
|
+
| MUI default-ramp reference | `bgcolor: 'grey.50'` (`QrSignupManager.jsx:340`) | **report only, do not fix** |
|
|
55
|
+
|
|
56
|
+
The third class routes through the theme, so it is not off-palette in the same way — but it points at
|
|
57
|
+
MUI's untouched grey ramp rather than at anything the estate decided. Report it as its own category
|
|
58
|
+
and leave the decision for later; folding a judgement call into a cleanup would be scope creep.
|
|
59
|
+
|
|
60
|
+
**Excluded from the scan, by operator decision:** the **generated print document** in
|
|
61
|
+
`QrSignupManager.jsx:185-240`. It is not app UI — it is a standalone HTML string with its own `body`,
|
|
62
|
+
`@media print` rules and `font-family: Arial`, rendered outside the React tree where **no theme is
|
|
63
|
+
available**. Its ten values (`#f5f7fb`, `#d9e2f2` ×3, `#e8f0ff`, `#f8faff`, `#ffffff` ×3, `#122033`,
|
|
64
|
+
`#23408e`) cannot take tokens. Excluding it is a correctness requirement, not a preference: scanning it
|
|
65
|
+
would produce ten permanent false positives, and exempting those one by one is exactly the
|
|
66
|
+
mass-exemption that `THEME-4` warned turns a check into a no-op. **Exclude the region and state the
|
|
67
|
+
reason in the code.** Making the printed poster follow each app's identity is a genuine idea and a
|
|
68
|
+
separate work order — not this one.
|
|
69
|
+
|
|
70
|
+
### The mappings, decided and each verified against `tokens.js`
|
|
71
|
+
|
|
72
|
+
Five values in `MFAComponent.jsx`:
|
|
73
|
+
|
|
74
|
+
| Where | Today | Target | Why |
|
|
75
|
+
|---|---|---|---|
|
|
76
|
+
| `:25` `MFA_ACTIVE_CARD_SX` background | `#f0fdf4` | `success.bg` (`#E5F4E9`) | light green tint marking the active factor |
|
|
77
|
+
| `:231` border | `1px solid #eee` | `divider` | it is a border |
|
|
78
|
+
| `:231` background | `bgcolor: 'white'` | `background.paper` | the named-colour case |
|
|
79
|
+
| `:244` background | `bgcolor: '#eee'` | `background.subtle` (`#F4F5F6`) | **a fill, not a border** |
|
|
80
|
+
| `:303` background | `bgcolor: '#f5f5f5'` | `background.subtle` (`#F4F5F6`) | near-exact match |
|
|
81
|
+
| `:314` border | `1px solid #ddd` | `divider` | it is a border |
|
|
82
|
+
|
|
83
|
+
**`#eee` appears in two different roles** — a border at `:231` and a **fill** at `:244`. A blind
|
|
84
|
+
find-and-replace would put a translucent border colour (`rgba(33,37,41,.10)`) into a filled box, which
|
|
85
|
+
is semantically wrong and visually lighter than intended. Map by role, not by value.
|
|
86
|
+
|
|
87
|
+
### Blast radius, and the operator's decision on it
|
|
88
|
+
|
|
89
|
+
No app imports `MFAComponent` directly — it is reached transitively: `AccountPage` renders
|
|
90
|
+
`SecurityComponent` (`AccountPage.jsx:223`) which renders `MFAComponent`, and **at least ten apps
|
|
91
|
+
mount `AccountPage`** — bigler-consult, cockpit, fitness-monitor, hpc-bridge, hram, innoservice,
|
|
92
|
+
jg-ferien, kerzenziehen, reimbursements. This is live, widely-mounted code, not a dead corner.
|
|
93
|
+
|
|
94
|
+
**Operator decision: map the values, and do not add a rendered gate for it.** The targets are near
|
|
95
|
+
neighbours of the values they replace, and the estate has no prototype for this screen to compare
|
|
96
|
+
against. **Do not re-add the two-width check** — but every changed value **must be listed in the
|
|
97
|
+
register note**, so a shift that lands unseen is at least recorded. That listing is the substitute for
|
|
98
|
+
looking.
|
|
99
|
+
|
|
100
|
+
### Non-goals / do not touch
|
|
101
|
+
|
|
102
|
+
- **The print document** (above). Excluded, unchanged.
|
|
103
|
+
- **`grey.*` references.** Reported, not fixed.
|
|
104
|
+
- **`DS-18`'s second half** — "which components can violate a rule". Still without a driver, and
|
|
105
|
+
`THEME-4` is now a cautionary data point for it: a check whose set comes from a heuristic can be
|
|
106
|
+
green while missing real cases.
|
|
107
|
+
- **App-side scanning.** An app's own components shadowing the baseline stays a follow-up; it wants
|
|
108
|
+
cockpit's adoption first so there is a real consumer to test against.
|
|
109
|
+
- No baseline token change. Part 2 consumes tokens; it does not add any.
|
|
110
|
+
- No change to `assertThemeComplete`'s surface registry, `createAppTheme`'s signature, the
|
|
111
|
+
`kitSxRegistry` entries, or any component's public props.
|
|
112
|
+
- `chartLabels.js`'s hex values are **baseline tokens** — leave them; if the scan flags them, the scan's
|
|
113
|
+
allowlist is wrong, not the file.
|
|
114
|
+
|
|
115
|
+
### Risks
|
|
116
|
+
|
|
117
|
+
- **A visual change in ten apps, published without a staging net.** A push to `main` touching `src/**`
|
|
118
|
+
publishes; the independent reviews are the only gate. The mitigation is the mandatory value listing,
|
|
119
|
+
plus `ui_reviewer` reading the diff against the mapping table above.
|
|
120
|
+
- **Mapping by value instead of by role** — the `#eee` trap. The table above exists so this is a
|
|
121
|
+
checkable instruction rather than a matter of care.
|
|
122
|
+
- **An over-eager scan.** `src/theme/` legitimately contains every token's hex definition, and
|
|
123
|
+
`chartLabels.js` consumes them. A scan without a correct allowlist floods the suite and gets
|
|
124
|
+
disabled, which is worse than no scan.
|
|
125
|
+
- **Wrong allowlist shape.** The allowlist must be derived from the palette rather than hand-listed, or
|
|
126
|
+
it goes stale the next time a token lands — `THEME-3` added one three days into this strand.
|
|
127
|
+
|
|
128
|
+
### Required tests to WRITE
|
|
129
|
+
|
|
130
|
+
1. **Non-vacuity for the scan:** a fixture source containing `bgcolor: '#123456'` produces a finding;
|
|
131
|
+
the same source using a palette token produces none.
|
|
132
|
+
2. **The named-colour class:** `bgcolor: 'white'` is flagged. This is the case a hex-only scan misses,
|
|
133
|
+
and it exists in the code today.
|
|
134
|
+
3. **The exclusion holds:** the print-document region produces **no** findings, and the exclusion is
|
|
135
|
+
scoped — a hex added elsewhere in `QrSignupManager.jsx` **is** still flagged.
|
|
136
|
+
4. **The allowlist is palette-derived:** adding a token to the palette makes a source using that value
|
|
137
|
+
pass, without editing the check.
|
|
138
|
+
5. **Part 1:** a fixture whose `sx` uses `bgcolor` collides with a baseline `backgroundColor` default
|
|
139
|
+
and is reported. Prove non-vacuity — this must fail before the map is extended.
|
|
140
|
+
6. `MFAComponent`'s existing spec stays green, and `THEME-4`'s shadowing check still returns no
|
|
141
|
+
findings for the kit.
|
|
142
|
+
|
|
143
|
+
Plus `tsc -p tsconfig.build.json --noEmit` clean. **No full-suite run** — affected set is the theme
|
|
144
|
+
module's specs plus `MFAComponent`'s.
|
|
145
|
+
|
|
146
|
+
### Verification
|
|
147
|
+
|
|
148
|
+
No rendered gate, per the operator decision above. What replaces it: the mapping table is the spec, and
|
|
149
|
+
the register note must list **every value changed, from and to**. If the implementation deviates from
|
|
150
|
+
the table for any of the six rows, that is a stop-and-report — the roles were resolved by reading the
|
|
151
|
+
code, and a different target means the reading was wrong.
|
|
152
|
+
|
|
153
|
+
### Parity guardrail
|
|
154
|
+
|
|
155
|
+
Six values change in one component; everything else in the kit renders identically. No behaviour, no
|
|
156
|
+
props, no permissions, no data contract.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## B. Implementation map
|
|
161
|
+
|
|
162
|
+
*Filled by the Orchestrator on `git pull` — see `AGENTS.md` → "Work Order".*
|
|
163
|
+
|
|
164
|
+
### Execution directive (read this first)
|
|
165
|
+
|
|
166
|
+
> **If you are the implementer reading this work order as your own specification: this section is
|
|
167
|
+
> NOT addressed to you.** It tells the Orchestrator how to invoke you. **You ARE that invocation —
|
|
168
|
+
> do NOT shell out to `codex exec`.**
|
|
169
|
+
>
|
|
170
|
+
> Implement through `codex exec` in the background — invoked directly via Bash (never the
|
|
171
|
+
> `debugger`/`*_coder` Agent wrappers) with BOTH flags `--skip-git-repo-check` and
|
|
172
|
+
> `--dangerously-bypass-approvals-and-sandbox`. **Pass the WO via stdin, not as a positional
|
|
173
|
+
> argument** (a positional arg hits Windows' command-line length limit — proven repeatedly in this
|
|
174
|
+
> repo). Fallback to direct Claude implementation only on Codex quota/rate-limit/non-zero exit — and
|
|
175
|
+
> note that the fallback flips authorship, so both reviewers stay mandatory either way.
|
|
176
|
+
>
|
|
177
|
+
> **Read `git log origin/main..HEAD` and `git status` before your own review.** On `SHELL-3` and
|
|
178
|
+
> `SHELL-4` Codex committed its own change and wrote a self-reported review into `WORK_ORDERS.md`;
|
|
179
|
+
> `THEME-4` was the first of the three where it did not. An implementer commit is a blocker to
|
|
180
|
+
> surface, and a register row naming a review the Orchestrator did not itself start is invalid.
|
|
181
|
+
|
|
182
|
+
### Context package
|
|
183
|
+
|
|
184
|
+
**Precondition confirmed:** `THEME-4` is landed and published (`c64e024`, register row `done`,
|
|
185
|
+
`package.json` reads `2.34.0`). Clean starting state, no implementer commit on top.
|
|
186
|
+
|
|
187
|
+
**Note on the WO's own arithmetic:** the Envelope's "Five values in `MFAComponent.jsx`" heading is
|
|
188
|
+
followed by a table of **six** rows (`:25`, `:231`×2, `:244`, `:303`, `:314`) — the register's own
|
|
189
|
+
summary already says "the six values it finds", so treat the table (six rows) as authoritative, the
|
|
190
|
+
heading as stale, consistent with two prior stale-count mismatches in this strand (`SHELL-4`'s
|
|
191
|
+
"ten to six", `THEME-4`'s "51 files").
|
|
192
|
+
|
|
193
|
+
**A likely seventh value the table omits — verify before assuming the table is exhaustive:**
|
|
194
|
+
`src/components/MFAComponent.jsx:313` has `bgcolor: 'white'` in the *same* sx object as the WO's row 6
|
|
195
|
+
(`:314`, `border: '1px solid #ddd'` → `divider`) — a recovery-code chip box, structurally identical in
|
|
196
|
+
role to row 3 (`:231`'s `bgcolor: 'white'` → `background.paper`, the QR-code box). If the new scan (Part
|
|
197
|
+
2) flags `:313` and it is not in the six-row table, this is not a table deviation to stop-and-report —
|
|
198
|
+
it is the same white-box-fill role already established at `:231`, map it identically to
|
|
199
|
+
`background.paper` and list it in the register note as a seventh, table-omitted finding the scan
|
|
200
|
+
caught. Confirm this reading against the actual code before implementing; do not assume the six-row
|
|
201
|
+
table is exhaustive just because the Envelope calls it "decided".
|
|
202
|
+
|
|
203
|
+
**Current file state (verified, so Codex works from real line numbers, not the WO's possibly-drifted
|
|
204
|
+
ones):**
|
|
205
|
+
```
|
|
206
|
+
src/components/MFAComponent.jsx:25 export const MFA_ACTIVE_CARD_SX = { bgcolor: '#f0fdf4' };
|
|
207
|
+
src/components/MFAComponent.jsx:231 <Box sx={{ p: 2, bgcolor: 'white', border: '1px solid #eee' }}>
|
|
208
|
+
src/components/MFAComponent.jsx:244 bgcolor: '#eee', (inside a multi-line sx, role: fill)
|
|
209
|
+
src/components/MFAComponent.jsx:303 <Box sx={{ bgcolor: '#f5f5f5', p: 2, borderRadius: 1 }}>
|
|
210
|
+
src/components/MFAComponent.jsx:313 bgcolor: 'white', (inside a multi-line sx -- the omitted 7th)
|
|
211
|
+
src/components/MFAComponent.jsx:314 border: '1px solid #ddd',
|
|
212
|
+
```
|
|
213
|
+
All six table rows' line numbers matched exactly on inspection — no drift.
|
|
214
|
+
|
|
215
|
+
**Token values to map to, confirmed against `src/theme/tokens.js`:**
|
|
216
|
+
- `divider: 'rgba(33,37,41,.10)'` (`tokens.js:69`)
|
|
217
|
+
- `background.paper: '#FFFFFF'` / `background.default: '#FAFAFA'` (`tokens.js:65-66`)
|
|
218
|
+
- `background.subtle: '#F4F5F6'` (`tokens.js:67`, landed by `THEME-3`)
|
|
219
|
+
- `success.bg: '#E5F4E9'` (`tokens.js:80`)
|
|
220
|
+
These are accessed in a component via `theme.palette.<path>`, i.e. `sx={{ bgcolor: 'divider' }}` /
|
|
221
|
+
`sx={{ bgcolor: 'background.subtle' }}` / `sx={{ bgcolor: 'success.bg' }}` (MUI resolves a dotted
|
|
222
|
+
palette-path string in `sx`) — this is the same string-token-reference pattern already used and
|
|
223
|
+
proven in `SHELL-4`'s `borderColor: 'divider'` fix. Do **not** import raw hex constants.
|
|
224
|
+
|
|
225
|
+
**Part 1 — extend `SPACING_SHORTHAND_LONGHANDS` (`src/theme/themeCompleteness.js:383`,
|
|
226
|
+
`expandShorthandProperty` at :402):** add a `bgcolor` → `['backgroundColor']` entry (and, while
|
|
227
|
+
touching this, consider whether `color`/other MUI palette-path aliases need the same treatment — the
|
|
228
|
+
WO names `bgcolor` as "the one with a real near-term risk", so that is the required minimum; do not
|
|
229
|
+
expand the alias table beyond what's verifiably a real MUI `sx` shorthand, to avoid the "write the
|
|
230
|
+
bound as an open one" instruction turning into an unbounded audit). Required test 5 (non-vacuity):
|
|
231
|
+
a fixture registry entry with `sx: { bgcolor: '#fff' }` against a MUI key whose baseline
|
|
232
|
+
`styleOverrides` sets `backgroundColor` must be flagged — construct this as a **fixture-only** test
|
|
233
|
+
(pass a custom `registry` + a fixture theme/component config to `assertKitSxDisjoint`, following the
|
|
234
|
+
existing fixture pattern already in `tests/themeCompleteness.test.js`'s `'kit sx disjointness'`
|
|
235
|
+
describe block, e.g. the `FixtureBottomNav`/`FixtureChip`/`FixtureButton` entries) since, per the
|
|
236
|
+
Envelope, there is genuinely no live `backgroundColor` collision in the real kit today — do not invent
|
|
237
|
+
one in the real registry just to exercise the code path.
|
|
238
|
+
|
|
239
|
+
**Part 2 — the off-palette colour scan.** New exported function in
|
|
240
|
+
`src/theme/themeCompleteness.js` (same file, same `{ findings: [{ surface, reason }] }` contract as
|
|
241
|
+
`assertThemeComplete`/`assertKitSxDisjoint`/`reportKitSxBypasses` — name it something like
|
|
242
|
+
`reportOffPaletteColours`, Codex's call). Reuse the existing hand-rolled brace/quote-aware source
|
|
243
|
+
scanning approach already proven in `reportKitSxBypasses` (`themeCompleteness.js`, functions
|
|
244
|
+
`jsxOpeningTag`/`topLevelSxValue` and the `sources.map(...)` normalisation shape shared with
|
|
245
|
+
`reportThemeAdoption`) rather than inventing a second scanning mechanism.
|
|
246
|
+
|
|
247
|
+
**Two known false-positive traps for the colour regex, found while preparing this map — test against
|
|
248
|
+
both explicitly:**
|
|
249
|
+
1. `src/components/charts/chartLabels.js:3-4` has a comment referencing GitHub issue numbers
|
|
250
|
+
`mui-x#18768` and `#18399` — a naive `/#[0-9a-f]{3,8}/i` pattern matches `#18768` as a false "hex
|
|
251
|
+
literal" (all five characters `1,8,7,6,8` are valid hex digits). The scan must not flag comment
|
|
252
|
+
text, or must otherwise be precise enough to skip this. This is exactly the "over-eager scan...
|
|
253
|
+
gets disabled" risk the Envelope names — verify the scan is blind to this file/line before calling
|
|
254
|
+
Part 2 done.
|
|
255
|
+
2. `src/theme/createAppTheme.js:45` has a comment mentioning `'#FFFFFF'`, and `:188` has a genuine
|
|
256
|
+
`'#FFFFFF'` string literal used for contrast-ratio computation (not a component style) — per the
|
|
257
|
+
Envelope's own risk note, `src/theme/` legitimately contains token hex definitions and must be
|
|
258
|
+
excluded from the scan's target set entirely (scan `src/components/`, `src/messaging/`,
|
|
259
|
+
`src/notifications/`, `src/pages/`, `src/auth/`, `src/layout/`, `src/onboarding/` — i.e. component
|
|
260
|
+
source, not `src/theme/` itself).
|
|
261
|
+
|
|
262
|
+
**The palette-derived allowlist (required test 4):** build the allowlist by walking
|
|
263
|
+
`BASELINE_PALETTE`/`BASELINE_STATIC` (or the fully-resolved output of `createAppTheme(...)`) and
|
|
264
|
+
collecting every hex/rgba string value found in it, rather than hand-listing values — this is what
|
|
265
|
+
required test 4 (adding a token to the palette should make a source using that value pass, without
|
|
266
|
+
editing the check) actually proves. `THEME-3` is cited in the Envelope as evidence a hand-listed
|
|
267
|
+
allowlist goes stale fast (a new baseline token landed three days into this strand).
|
|
268
|
+
|
|
269
|
+
**Named-CSS-colour detection (required test 2):** `bgcolor: 'white'` must be flagged same as a hex
|
|
270
|
+
literal — CSS named colours are a small, fixed, enumerable set (`white`, `black`, `red`, `grey`,
|
|
271
|
+
etc. — the 16 basic CSS colour keywords are the practical minimum; do not attempt to support the full
|
|
272
|
+
147-name X11/CSS list unless a real instance demands it, per the WO's own anti-gold-plating stance).
|
|
273
|
+
|
|
274
|
+
**The `grey.*` report-only class (required, do not fix):** `src/components/QrSignupManager.jsx:340`
|
|
275
|
+
has `bgcolor: 'grey.50'` — this is a **dotted MUI theme-path string**, not a hex/named-colour literal,
|
|
276
|
+
so it needs its own detection branch (match `/^[a-z]+\.\d+$/i`-shaped sx string values referencing
|
|
277
|
+
MUI's stock palette ramps, distinct from both the hex/named-colour findings and the
|
|
278
|
+
divider/background.subtle/success.bg *baseline* token-path strings this same WO is busy introducing
|
|
279
|
+
elsewhere — do not let the scan flag the very token references Part 1's own fixes create). Report it
|
|
280
|
+
under a distinct `reason` wording (e.g. "uses MUI's untouched grey ramp, not a baseline token — review,
|
|
281
|
+
do not auto-fix") so a consumer of the findings can filter report-only from must-fix.
|
|
282
|
+
|
|
283
|
+
**The print-document exclusion (required test 3):** exclude the template-literal region inside
|
|
284
|
+
`QrSignupManager.jsx`'s `printWindow.document.write(\`...\`)` call — currently spans roughly
|
|
285
|
+
`:178`-`:266` (verify exact bounds by locating the `printWindow.document.write(` call and its
|
|
286
|
+
matching closing backtick+paren, not by trusting these line numbers, since the WO's own `:185-240`
|
|
287
|
+
estimate was already off by several lines against the current file). The exclusion must be scoped
|
|
288
|
+
narrowly enough that a hex literal added elsewhere in the same file (outside that one template
|
|
289
|
+
literal) still gets flagged — required test 3's second half.
|
|
290
|
+
|
|
291
|
+
### Invariants / do-not-touch
|
|
292
|
+
|
|
293
|
+
No change to `assertThemeComplete`'s surface registry, `createAppTheme`'s signature, `kitSxRegistry`
|
|
294
|
+
entries structure, or any component's public props. No baseline token added (Part 2 consumes existing
|
|
295
|
+
tokens only). `chartLabels.js`'s own values are not colours to fix (see trap above) — if the finished
|
|
296
|
+
scan flags anything in `src/theme/**`, that is a scan-scope bug, not a file to edit.
|
|
297
|
+
|
|
298
|
+
### Addendum — operator decision on the scan's broader findings (chunk 2)
|
|
299
|
+
|
|
300
|
+
The first implementation chunk correctly stopped without committing and reported a real scope
|
|
301
|
+
question instead of deciding it: with the off-palette scan's detection widened beyond hex + basic
|
|
302
|
+
named colours (per Part 2), it also catches two values **outside `MFAComponent`**, which the
|
|
303
|
+
Envelope's Parity guardrail ("six values change in one component; everything else in the kit renders
|
|
304
|
+
identically") did not anticipate:
|
|
305
|
+
|
|
306
|
+
1. `src/components/SocialLoginButtons.jsx:37` — `border: '1px solid rgba(0,0,0,0.2)'` on the Google
|
|
307
|
+
icon circle. A real rendered `sx` border, same class of finding as the MFA border fixes.
|
|
308
|
+
2. `src/components/charts/exportChart.js:48` — `context.fillStyle = 'white'` inside a **Canvas 2D API
|
|
309
|
+
call** (PNG export), not JSX/`sx` — structurally like the already-excluded print document in that it
|
|
310
|
+
runs outside the React/theme tree, but unlike it, plumbing a resolved colour in is straightforward
|
|
311
|
+
(the caller has `useTheme()` access; a colour can be passed as a parameter to the export function).
|
|
312
|
+
|
|
313
|
+
**Operator decision (this session): fix both**, per Codex's own recommended option. This is an
|
|
314
|
+
explicit, approved widening of scope beyond the original Envelope's blast radius — record it as such
|
|
315
|
+
in the register note, do not fold it in as if the original Envelope already covered it.
|
|
316
|
+
|
|
317
|
+
**Scope of the fix:**
|
|
318
|
+
- Widen the scan's colour detection to catch `rgba(...)` literals (not just hex + the basic named-colour
|
|
319
|
+
set), so this class is caught mechanically going forward, not just this one instance.
|
|
320
|
+
- `SocialLoginButtons.jsx:37`: map to `divider` (the same token every other border-role finding in this
|
|
321
|
+
WO maps to) — confirm this reads correctly next to the icon (a translucent, lighter border than the
|
|
322
|
+
current `rgba(0,0,0,0.2)`; this is the intended effect of holding to the baseline, not a regression).
|
|
323
|
+
- `exportChart.js:48`: resolve the fill colour from the theme at the call site (the component invoking
|
|
324
|
+
the export utility has `useTheme()`), and pass it into `exportChart`'s existing call rather than
|
|
325
|
+
hardcoding a new default inside the utility — check `exportChart.js`'s current signature and its
|
|
326
|
+
caller(s) (`ChartFrame.jsx`, most likely) before deciding the exact parameter shape; prefer the
|
|
327
|
+
smallest signature change that removes the hardcoded literal, not a redesign of the export API.
|
|
328
|
+
- Both new value changes must be listed in the register note the same way as the seven MFA values
|
|
329
|
+
(from → to, with role), per the Envelope's "every changed value must be listed" requirement, which
|
|
330
|
+
the operator's decision extends to cover these two as well.
|
|
331
|
+
- Re-run both reviewers (`reviewer` + `ui_reviewer`) on the complete, widened diff — the WO's original
|
|
332
|
+
review requirement stands, now over a larger diff.
|
|
333
|
+
|
|
334
|
+
This addendum does not change anything else in Part A/B above — the six/seven MFA mappings, the
|
|
335
|
+
allowlist requirement, the print-document exclusion, and the `grey.*` report-only class are unchanged.
|
|
336
|
+
|
|
337
|
+
### Mini-handover
|
|
338
|
+
|
|
339
|
+
Repo: `ui-core-micha` (`C:\Users\biglmi\Documents\webapps\ui-core-micha`), branch `main`.
|
|
340
|
+
WO: `work-orders/THEME-5.md`. Follow `orchestrate-codex`. **Chunk 2**: implement the Addendum above on
|
|
341
|
+
top of chunk 1's uncommitted working-tree state — do not discard chunk 1's work, extend it.
|