@micha.bigler/ui-core-micha 3.14.4 → 4.0.1
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/CHANGELOG.md +29 -0
- package/README.md +7 -0
- package/dist/chat/kitSxRegistry.js +9 -0
- package/dist/components/charts/kitSxRegistry.js +6 -0
- package/dist/entries/charts.js +6 -0
- package/dist/entries/chat.js +8 -0
- package/dist/entries/markdown.js +1 -0
- package/dist/index.js +0 -14
- package/dist/pages/AccountPage.js +1 -2
- package/dist/pages/LoginPage.js +1 -2
- package/dist/pages/PasswordChangePage.js +1 -2
- package/dist/pages/PasswordInvitePage.js +1 -2
- package/dist/pages/PasswordResetRequestPage.js +1 -2
- package/dist/pages/SignUpPage.js +1 -2
- package/dist/pages/SignupConfirmPage.js +1 -2
- package/dist/theme/kitSxEntry.js +11 -0
- package/dist/theme/kitSxRegistry.js +2 -15
- package/package.json +31 -7
- package/.github/workflows/ci.yml +0 -35
- package/.github/workflows/publish.yml +0 -126
- package/DESIGN.md +0 -60
- package/WORK_ORDERS.md +0 -150
- package/dev/entries.jsx +0 -721
- package/dev/fixtures.js +0 -26
- package/dev/main.jsx +0 -75
- package/dev/mockTransport.jsx +0 -128
- package/docs/CHART-LAYOUT.md +0 -157
- package/docs/DARK-TOKENS.md +0 -140
- package/docs/TYPE-SCALE.md +0 -111
- package/docs/messaging-deviations.md +0 -118
- package/index.html +0 -12
- package/renovate.json +0 -10
- package/scripts/chart-api-census.mjs +0 -415
- package/src/auth/AuthContext.jsx +0 -158
- package/src/auth/ReauthModal.jsx +0 -82
- package/src/auth/UserMenu.jsx +0 -121
- package/src/auth/apiClient.jsx +0 -232
- package/src/auth/authApi.jsx +0 -539
- package/src/auth/authConfig.jsx +0 -34
- package/src/auth/reauth.js +0 -47
- package/src/chat/ChatComposer.jsx +0 -36
- package/src/chat/ChatList.jsx +0 -87
- package/src/chat/ChatThread.jsx +0 -128
- package/src/chat/ChatWorkspace.jsx +0 -244
- package/src/chat/MarkdownReply.jsx +0 -22
- package/src/chat/ModelPicker.jsx +0 -85
- package/src/chat/api.js +0 -18
- package/src/chat/useChatSocket.js +0 -32
- package/src/chat/wire.js +0 -7
- package/src/components/AccessCodeManager.jsx +0 -288
- package/src/components/AccessCodeSingleUseToggle.jsx +0 -92
- package/src/components/AllowedEmailDomainsManager.jsx +0 -92
- package/src/components/AuthFactorRequirementCard.jsx +0 -95
- package/src/components/BulkInviteCsvTab.jsx +0 -198
- package/src/components/EmptyState.jsx +0 -38
- package/src/components/LoginForm.jsx +0 -159
- package/src/components/MFAComponent.jsx +0 -350
- package/src/components/MfaLoginComponent.jsx +0 -252
- package/src/components/MobileBottomNav.jsx +0 -82
- package/src/components/PasskeysComponent.jsx +0 -252
- package/src/components/PasswordChangeForm.jsx +0 -87
- package/src/components/PasswordResetRequestForm.jsx +0 -43
- package/src/components/PasswordSetForm.jsx +0 -97
- package/src/components/ProfileComponent.jsx +0 -348
- package/src/components/QrSignupManager.jsx +0 -404
- package/src/components/QrSignupValidityManager.jsx +0 -106
- package/src/components/RegistrationMethodsManager.jsx +0 -150
- package/src/components/SecurityComponent.jsx +0 -141
- package/src/components/SocialLoginButtons.jsx +0 -83
- package/src/components/SoftChip.jsx +0 -93
- package/src/components/StatTile.jsx +0 -39
- package/src/components/SupportRecoveryRequestsTab.jsx +0 -482
- package/src/components/TurnstileWidget.jsx +0 -99
- package/src/components/UserInviteComponent.jsx +0 -76
- package/src/components/UserListComponent.jsx +0 -618
- package/src/components/charts/BarChart.jsx +0 -102
- package/src/components/charts/ChartFrame.jsx +0 -214
- package/src/components/charts/LineChart.jsx +0 -126
- package/src/components/charts/ScatterChart.jsx +0 -299
- package/src/components/charts/TimeSeriesChart.jsx +0 -300
- package/src/components/charts/chartDefaults.js +0 -644
- package/src/components/charts/chartLabels.js +0 -36
- package/src/components/charts/exportChart.js +0 -258
- package/src/components/charts/formatters.js +0 -39
- package/src/components/charts/palette.js +0 -33
- package/src/components/charts/yearTickInterval.js +0 -7
- package/src/i18n/authTranslations.ts +0 -2651
- package/src/i18n/chartsTranslations.ts +0 -91
- package/src/i18n/chatTranslations.ts +0 -55
- package/src/i18n/messagingTranslations.ts +0 -120
- package/src/i18n/notificationsTranslations.ts +0 -32
- package/src/i18n/onboardingTranslations.ts +0 -29
- package/src/i18n/sectionNavTranslations.ts +0 -20
- package/src/i18n/uiCoreTranslations.js +0 -29
- package/src/i18n/userMenuTranslations.ts +0 -5
- package/src/index.js +0 -158
- package/src/layout/PageLayout.jsx +0 -36
- package/src/layout/SectionNav.jsx +0 -320
- package/src/messaging/AttachmentList.jsx +0 -145
- package/src/messaging/Composer.jsx +0 -197
- package/src/messaging/ConversationLaunchers.jsx +0 -51
- package/src/messaging/ConversationList.jsx +0 -109
- package/src/messaging/DirectMessageLauncher.jsx +0 -112
- package/src/messaging/MessageBubble.jsx +0 -183
- package/src/messaging/MessagingProvider.jsx +0 -0
- package/src/messaging/MessagingScopeConfig.jsx +0 -24
- package/src/messaging/PollCard.jsx +0 -163
- package/src/messaging/ReactionBar.jsx +0 -43
- package/src/messaging/ReadTicks.jsx +0 -82
- package/src/messaging/Thread.jsx +0 -195
- package/src/messaging/api.js +0 -48
- package/src/messaging/composerImageCompression.js +0 -35
- package/src/messaging/linkifyText.jsx +0 -37
- package/src/notifications/NotificationBell.jsx +0 -84
- package/src/notifications/NotificationSettings.jsx +0 -330
- package/src/notifications/NotificationsProvider.jsx +0 -224
- package/src/notifications/PopupSurface.jsx +0 -105
- package/src/notifications/api.js +0 -55
- package/src/notifications/feedApi.js +0 -18
- package/src/notifications/realtime.jsx +0 -138
- package/src/notifications/serviceWorker/sw.js +0 -50
- package/src/onboarding/OnboardingProvider.jsx +0 -326
- package/src/onboarding/OnboardingWizard.jsx +0 -61
- package/src/onboarding/WizardDialogShell.jsx +0 -51
- package/src/onboarding/api.js +0 -13
- package/src/onboarding/stepSelection.js +0 -16
- package/src/onboarding/steps/BrowserPushStep.jsx +0 -121
- package/src/onboarding/steps/CompleteNameStep.jsx +0 -46
- package/src/onboarding/steps/CookieConsentStep.jsx +0 -133
- package/src/onboarding/steps/PwaInstallStep.jsx +0 -47
- package/src/pages/AccountPage.jsx +0 -394
- package/src/pages/LoginPage.jsx +0 -343
- package/src/pages/PasswordChangePage.jsx +0 -62
- package/src/pages/PasswordInvitePage.jsx +0 -177
- package/src/pages/PasswordResetRequestPage.jsx +0 -68
- package/src/pages/SignUpPage.jsx +0 -268
- package/src/pages/SignupConfirmPage.jsx +0 -155
- package/src/testing/checkKitIntegration.js +0 -233
- package/src/theme/createAppTheme.js +0 -423
- package/src/theme/fonts.js +0 -3
- package/src/theme/index.js +0 -21
- package/src/theme/kitSxRegistry.js +0 -285
- package/src/theme/themeCompleteness.js +0 -1045
- package/src/theme/tokens.js +0 -478
- package/src/utils/auth-errors.js +0 -76
- package/src/utils/authService.js +0 -223
- package/src/utils/resolveErrorText.js +0 -28
- package/src/utils/webauthn.js +0 -51
- package/tests/AccountPage.profileStatements.test.jsx +0 -162
- package/tests/AccountPage.test.jsx +0 -200
- package/tests/AuthContext.test.jsx +0 -129
- package/tests/BarChart.test.jsx +0 -112
- package/tests/BrowserPushStep.test.jsx +0 -110
- package/tests/ChartFrame.test.jsx +0 -336
- package/tests/ConversationList.test.jsx +0 -144
- package/tests/CookieConsentStep.test.jsx +0 -69
- package/tests/EmptyState.test.jsx +0 -62
- package/tests/LineChart.test.jsx +0 -80
- package/tests/MessagingProvider.test.jsx +0 -50
- package/tests/MobileBottomNav.test.jsx +0 -319
- package/tests/NotificationBell.test.jsx +0 -60
- package/tests/NotificationSettings.test.jsx +0 -276
- package/tests/NotificationsProvider.test.jsx +0 -240
- package/tests/OnboardingProvider.test.jsx +0 -294
- package/tests/OnboardingWizard.test.jsx +0 -143
- package/tests/PasswordChangeForm.test.jsx +0 -70
- package/tests/PasswordInvitePage.test.jsx +0 -142
- package/tests/PasswordSetForm.test.jsx +0 -70
- package/tests/PopupSurface.test.jsx +0 -142
- package/tests/ProfileComponent.refresh.test.jsx +0 -194
- package/tests/QrSignupManager.registrationContext.test.jsx +0 -106
- package/tests/QrSignupManagerInfoBox.test.jsx +0 -49
- package/tests/ScatterChart.test.jsx +0 -270
- package/tests/SectionNav.test.jsx +0 -363
- package/tests/SignUpPage.test.jsx +0 -208
- package/tests/SoftChip.test.jsx +0 -105
- package/tests/StatTile.test.jsx +0 -57
- package/tests/Thread.test.jsx +0 -151
- package/tests/TimeSeriesChart.test.jsx +0 -367
- package/tests/UserListComponent.test.jsx +0 -192
- package/tests/UserMenu.test.jsx +0 -171
- package/tests/apiClientLanguage.test.js +0 -33
- package/tests/apiClientPublicPaths.test.js +0 -178
- package/tests/authApiLogin.test.js +0 -42
- package/tests/authApiRegistration.test.js +0 -31
- package/tests/authErrorCodeRendering.test.jsx +0 -77
- package/tests/authErrors.test.js +0 -74
- package/tests/authTranslations.test.js +0 -74
- package/tests/chart-api-census.test.js +0 -366
- package/tests/chartAxisTickBand.test.jsx +0 -95
- package/tests/chartDefaults.test.js +0 -902
- package/tests/chartLabels.test.js +0 -50
- package/tests/chartsPalette.test.js +0 -99
- package/tests/chatApi.test.js +0 -48
- package/tests/chatDriverNames.test.jsx +0 -71
- package/tests/chatExports.test.js +0 -3
- package/tests/chatList.test.jsx +0 -84
- package/tests/chatPicker.test.jsx +0 -82
- package/tests/chatSocket.test.jsx +0 -26
- package/tests/chatThread.test.jsx +0 -116
- package/tests/chatTranslations.test.js +0 -47
- package/tests/chatWorkspace.test.jsx +0 -234
- package/tests/checkKitIntegration.test.jsx +0 -219
- package/tests/createAppTheme.test.js +0 -132
- package/tests/createAppThemeDark.test.js +0 -127
- package/tests/createAppThemeLightGuard.test.js +0 -40
- package/tests/createAppThemePageContrast.test.js +0 -108
- package/tests/createAppThemeTypography.test.js +0 -53
- package/tests/errorCallSiteGuard.test.js +0 -32
- package/tests/exportChart.test.js +0 -313
- package/tests/feedApi.test.js +0 -46
- package/tests/fixtures/light-theme-baseline.json +0 -2234
- package/tests/i18nAggregate.test.js +0 -120
- package/tests/i18nGermanVariant.test.js +0 -65
- package/tests/loginPageErrorResolution.test.jsx +0 -102
- package/tests/messagingApi.test.js +0 -32
- package/tests/messagingChunk6.test.jsx +0 -116
- package/tests/messagingCompactBubble.test.jsx +0 -64
- package/tests/messagingComposer.test.jsx +0 -136
- package/tests/messagingComposerChunk5.test.jsx +0 -113
- package/tests/messagingContractConformance.test.js +0 -69
- package/tests/messagingDirectMessageLauncher.test.jsx +0 -151
- package/tests/messagingExports.test.js +0 -21
- package/tests/messagingInteractions.test.jsx +0 -136
- package/tests/messagingLastMessagePreview.test.jsx +0 -93
- package/tests/messagingLinkify.test.jsx +0 -51
- package/tests/messagingMessageActions.test.jsx +0 -163
- package/tests/messagingMsg6.test.jsx +0 -105
- package/tests/messagingMsg6f.test.jsx +0 -155
- package/tests/messagingMsg6g.test.jsx +0 -166
- package/tests/messagingMsg6h.test.jsx +0 -136
- package/tests/messagingMsg6i.test.jsx +0 -129
- package/tests/messagingPollRendering.test.jsx +0 -142
- package/tests/messagingReactionMerge.test.jsx +0 -77
- package/tests/messagingReadTicksTooltip.test.jsx +0 -36
- package/tests/messagingThreadReceipts.test.jsx +0 -178
- package/tests/messagingThreadingQuoting.test.jsx +0 -87
- package/tests/messagingUnreadLifecycle.test.jsx +0 -78
- package/tests/notificationsApi.test.js +0 -41
- package/tests/notificationsExports.test.js +0 -34
- package/tests/onboardingDescriptors.test.js +0 -132
- package/tests/packageTreeShaking.test.js +0 -126
- package/tests/realtime.test.jsx +0 -219
- package/tests/resolveErrorText.test.js +0 -72
- package/tests/stepSelection.test.js +0 -53
- package/tests/themeCompleteness.test.js +0 -626
- package/tests/timeSeriesLegend.test.js +0 -99
- package/tests/userScreenTranslations.test.jsx +0 -218
- package/tsconfig.build.json +0 -18
- package/vite.config.mjs +0 -6
- package/work-orders/AUTH-1.md +0 -74
- package/work-orders/AUTH-2.md +0 -74
- package/work-orders/AUTH-4.md +0 -183
- package/work-orders/AUTH-5.md +0 -154
- package/work-orders/AUTH-7.md +0 -181
- package/work-orders/AUTH-8.md +0 -184
- package/work-orders/CHART-1.md +0 -285
- package/work-orders/CHART-2.md +0 -222
- package/work-orders/CHART-3.md +0 -163
- package/work-orders/CHART-4.md +0 -203
- package/work-orders/CHART-5.md +0 -226
- package/work-orders/CHART-6.md +0 -428
- package/work-orders/CHART-7.md +0 -175
- package/work-orders/DX-1.md +0 -169
- package/work-orders/DX-2.md +0 -188
- package/work-orders/DX-3.md +0 -195
- package/work-orders/I18N-1.md +0 -254
- package/work-orders/I18N-3.md +0 -207
- package/work-orders/MSG-3.md +0 -375
- package/work-orders/MSG-3b.md +0 -1002
- package/work-orders/MSG-3c.md +0 -378
- package/work-orders/MSG-3d.md +0 -268
- package/work-orders/MSG-3e.md +0 -164
- package/work-orders/MSG-3f.md +0 -391
- package/work-orders/MSG-6e.md +0 -308
- package/work-orders/MSG-6f.md +0 -214
- package/work-orders/MSG-6g.md +0 -244
- package/work-orders/MSG-6h.md +0 -238
- package/work-orders/MSG-6i.md +0 -271
- package/work-orders/MSG-6j.md +0 -117
- package/work-orders/NOTIF-12.md +0 -214
- package/work-orders/NOTIF-13.md +0 -142
- package/work-orders/NOTIF-14.md +0 -151
- package/work-orders/PRIM-1.md +0 -177
- package/work-orders/SHELL-1.md +0 -255
- package/work-orders/SHELL-2.md +0 -197
- package/work-orders/SHELL-3.md +0 -359
- package/work-orders/SHELL-4.md +0 -351
- package/work-orders/SHELL-5.md +0 -345
- package/work-orders/SHELL-6.md +0 -210
- package/work-orders/THEME-1.md +0 -587
- package/work-orders/THEME-10.md +0 -303
- package/work-orders/THEME-11.md +0 -208
- package/work-orders/THEME-2.md +0 -339
- package/work-orders/THEME-3.md +0 -210
- package/work-orders/THEME-4.md +0 -271
- package/work-orders/THEME-5.md +0 -341
- package/work-orders/THEME-6.md +0 -247
- package/work-orders/THEME-7.md +0 -82
- package/work-orders/THEME-8.md +0 -211
- package/work-orders/THEME-9.md +0 -194
- package/work-orders/UCM-AUTH-10.md +0 -490
- package/work-orders/UCM-AUTH-11.md +0 -185
- package/work-orders/UCM-AUTH-12.md +0 -98
- package/work-orders/UCM-AUTH-13.md +0 -47
- package/work-orders/UCM-AUTH-9.md +0 -207
- package/work-orders/UCM-CHART-10.md +0 -150
- package/work-orders/UCM-CHART-11.md +0 -132
- package/work-orders/UCM-CHART-12.md +0 -348
- package/work-orders/UCM-CHART-13.md +0 -122
- package/work-orders/UCM-CHART-14.md +0 -198
- package/work-orders/UCM-CHART-15.md +0 -187
- package/work-orders/UCM-CHART-16.md +0 -169
- package/work-orders/UCM-CHART-17.md +0 -195
- package/work-orders/UCM-CHART-18.md +0 -200
- package/work-orders/UCM-CHART-8.md +0 -147
- package/work-orders/UCM-CHART-9.md +0 -265
- package/work-orders/UCM-CHAT-1.md +0 -190
- package/work-orders/UCM-CHAT-2.md +0 -75
- package/work-orders/UCM-CI-1.md +0 -65
- package/work-orders/UCM-DEP-1.md +0 -63
- package/work-orders/UCM-I18N-4.md +0 -226
- package/work-orders/UCM-I18N-5.md +0 -211
- package/work-orders/UCM-MSG-20.md +0 -192
- package/work-orders/UCM-PRIM-2.md +0 -114
- package/work-orders/UCM-SHELL-7.md +0 -134
- package/work-orders/UCM-SHELL-8.md +0 -125
- package/work-orders/UCM-TEST-1.md +0 -304
- package/work-orders/UCM-THEME-13.md +0 -69
- package/work-orders/UCM-THEME-14.md +0 -312
- package/work-orders/UCM-THEME-15.md +0 -356
- package/work-orders/UCM-THEME-16.md +0 -80
- package/work-orders/UCM-THEME-17.md +0 -111
- package/work-orders/UCM-THEME-18.md +0 -184
- package/work-orders/assets/AUTH-4-user-list-card.html +0 -407
- package/work-orders/assets/PRIM-1-dashboard-primitives.html +0 -624
- package/work-orders/assets/SHELL-2-account-navigation.html +0 -1159
- package/work-orders/assets/THEME-1-baseline-reference-sheet.html +0 -1352
- package/work-orders/assets/UCM-CHAT-1-ai-chat.html +0 -447
- package/work-orders/assets/UCM-THEME-13-dark-prototype.html +0 -390
- package/work-orders/assets/UCM-THEME-17-type-scale.html +0 -391
package/work-orders/THEME-6.md
DELETED
|
@@ -1,247 +0,0 @@
|
|
|
1
|
-
# THEME-6 — An app-side check for `sx` values the theme already gives
|
|
2
|
-
|
|
3
|
-
**Target repo:** `ui-core-micha` (branch `main` — this repo has no `develop`)
|
|
4
|
-
**Tier:** 3 (shared core)
|
|
5
|
-
**Review:** independent `reviewer` — mandatory (new logic). **`ui_reviewer` does not apply**: this WO
|
|
6
|
-
adds a check and fixes nothing, so no rendered output changes. If that turns out to be false, it
|
|
7
|
-
applies after all.
|
|
8
|
-
**Version target:** the next **minor** after the published version — a new exported check is additive
|
|
9
|
-
API. Read the published version at implementation time.
|
|
10
|
-
**Strand:** `DS-18`, the app-side half. Trigger fired when cockpit adopted `createAppTheme` (`UI-6`);
|
|
11
|
-
deferred once because cockpit was mid-rebuild in `UI-3`, **which has since landed.**
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## A. Envelope
|
|
16
|
-
|
|
17
|
-
### Goal
|
|
18
|
-
|
|
19
|
-
`THEME-4` made it mechanical that no **kit** component defeats the baseline. Apps have no equivalent:
|
|
20
|
-
cockpit alone carries **464 `sx` props across 37 files** (measured 2026-08-11), and nothing checks any
|
|
21
|
-
of them against the theme they sit on.
|
|
22
|
-
|
|
23
|
-
Give apps an exported check they call from their own suite, the way they already call
|
|
24
|
-
`assertThemeComplete`.
|
|
25
|
-
|
|
26
|
-
### This is NOT a port of `THEME-4`, and getting that wrong would flood the app
|
|
27
|
-
|
|
28
|
-
In the **kit**, an `sx` value that duplicates a baseline default is a bug by definition: the default
|
|
29
|
-
becomes inert for every consumer. So `THEME-4` compares **key sets** and demands disjointness.
|
|
30
|
-
|
|
31
|
-
In an **app**, `sx` beating the theme is **the intended mechanism** — that is how a screen customises
|
|
32
|
-
one instance. A key-collision check over 464 props would flag mostly legitimate customisation, get
|
|
33
|
-
blanket-exempted, and become the no-op `THEME-4`'s own WO warned about.
|
|
34
|
-
|
|
35
|
-
**So the app-side rule is different: flag an `sx` value that is *equal* to what the theme already
|
|
36
|
-
resolves for that component and property.** Not "you overrode a default" — "you re-stated a value you
|
|
37
|
-
already had". That is dead weight which **silently diverges the next time the token changes**, which is
|
|
38
|
-
the real failure mode and the one worth a check.
|
|
39
|
-
|
|
40
|
-
Grounded in cockpit, measured: `borderColor: 'divider'` (×2) and `bgcolor: 'background.paper'` (×3) on
|
|
41
|
-
surfaces whose theme already sets exactly that, and `borderRadius: 1` (×3) which resolves to the
|
|
42
|
-
baseline's own `shape.borderRadius`. Those are the findings this check exists for.
|
|
43
|
-
|
|
44
|
-
### Scope
|
|
45
|
-
|
|
46
|
-
**1. An exported check, source-level.** Same finding contract as its siblings
|
|
47
|
-
(`{ findings: [{ surface, reason }] }`), same shape as `reportThemeAdoption` and
|
|
48
|
-
`reportOffPaletteColours`: it takes the app's own sources plus its theme, and returns findings. The app
|
|
49
|
-
globs its `src/**` in its own test and passes them.
|
|
50
|
-
|
|
51
|
-
For each `sx` entry it can attribute to a MUI component the theme styles, resolve what the theme gives
|
|
52
|
-
for that property and flag **equality**. The attribution comes from the JSX element name in the source
|
|
53
|
-
text — `<Paper sx={{ borderRadius: 1 }}>` → `MuiPaper` → compare against
|
|
54
|
-
`theme.components.MuiPaper.styleOverrides.root.borderRadius`.
|
|
55
|
-
|
|
56
|
-
**2. Report-only, with a ratchet.** New findings must not turn a green app red on a pin bump. Ship it
|
|
57
|
-
**report-only**, and let each app make it a hard assertion in its own cleanup WO — the same ratchet
|
|
58
|
-
`DS-2` used for `assertThemeComplete`, and for the same reason.
|
|
59
|
-
|
|
60
|
-
**3. Run it against cockpit and report the count. Fix nothing.** cockpit is the first real consumer and
|
|
61
|
-
the reason the trigger fired. The cleanup is cockpit's own work order, not this one — bundling an
|
|
62
|
-
unbounded app cleanup into a shared-core WO is what `AUTH-4` was split out of `DS-11` to avoid.
|
|
63
|
-
|
|
64
|
-
### Reuse, do not rebuild — and one gap in the reuse
|
|
65
|
-
|
|
66
|
-
**The hardcoded-colour half already exists and is already app-callable.**
|
|
67
|
-
`reportOffPaletteColours(sources, { palette })` (`themeCompleteness.js:759`) takes sources and an
|
|
68
|
-
optional palette, so an app can pass its own files and its own palette today. cockpit's
|
|
69
|
-
`bgcolor: '#fff'` (×2) is exactly what it reports. **Do not duplicate it.**
|
|
70
|
-
|
|
71
|
-
**But its skip pattern assumes ucm's layout.** It skips paths matching `src/theme/` — with a trailing
|
|
72
|
-
slash (`:768`). ucm's tokens live in `src/theme/tokens.js`; an app's theme is usually
|
|
73
|
-
`src/theme.js`, which **does not match** and therefore gets scanned, so every identity token in it
|
|
74
|
-
(cockpit: `#3D5A99`, `#eff2f7`, `#e4e8f1`, …) would be reported as off-palette.
|
|
75
|
-
|
|
76
|
-
Resolve it **app-side**, not by widening the pattern: the app excludes its own theme file from the
|
|
77
|
-
sources it passes. That keeps ucm's behaviour unchanged and puts the knowledge where the layout is
|
|
78
|
-
known. Say so in the check's doc comment so the next app does not rediscover it.
|
|
79
|
-
|
|
80
|
-
### The bound, and it is open
|
|
81
|
-
|
|
82
|
-
Attribution from source text is a **heuristic**. It will miss `sx` on a variable, spread props, an
|
|
83
|
-
aliased import (`import { Paper as Surface }`), a `styled()` component, and a MUI component rendered
|
|
84
|
-
through `component={...}`. **Write the bound as open — "unknown attribution gaps remain" — not as a
|
|
85
|
-
list.** `THEME-4`'s WO enumerated its limits and the first real miss (shorthand alias spelling) was not
|
|
86
|
-
on the list; `THEME-5` was told to phrase it openly and that phrasing then held when the fourth
|
|
87
|
-
shadowing layer appeared. An enumeration reads as coverage.
|
|
88
|
-
|
|
89
|
-
This check is a lower bound on redundancy, and green means "nothing found by this method".
|
|
90
|
-
|
|
91
|
-
### Non-goals / do not touch
|
|
92
|
-
|
|
93
|
-
- **No fixes anywhere.** Not in cockpit, not in the kit. This WO ships a check and a count.
|
|
94
|
-
- **No change to `reportOffPaletteColours`**, `assertKitSxDisjoint`, `reportKitSxBypasses`,
|
|
95
|
-
`reportThemeAdoption` or `assertThemeComplete` — including no widening of the `src/theme/` skip.
|
|
96
|
-
- **Not a hard assertion anywhere yet.** Report-only; the ratchet is each app's own.
|
|
97
|
-
- `DS-18`'s remaining half — "which components *can violate* a rule", derived from a
|
|
98
|
-
`grep 'shadows\['` lower bound — stays out and stays without a driver.
|
|
99
|
-
- No baseline token, component default or public prop change.
|
|
100
|
-
|
|
101
|
-
### Risks
|
|
102
|
-
|
|
103
|
-
- **False positives are the failure mode**, not false negatives. A check that flags legitimate
|
|
104
|
-
customisation gets switched off. That is why it compares values rather than keys, and why it ships
|
|
105
|
-
report-only.
|
|
106
|
-
- **The count from cockpit may be large.** 464 props is the denominator. If it is large enough that no
|
|
107
|
-
app could plausibly act on it, that is a finding to report — the check may need a narrower first
|
|
108
|
-
scope (e.g. only the ~23 component keys the baseline actually styles) rather than shipping noise.
|
|
109
|
-
- **No staging net.** A version bump on `main` publishes; the independent review is the only gate.
|
|
110
|
-
- **Other sessions are frequently active in this repo.** Read `git status` and
|
|
111
|
-
`git log origin/main..HEAD` before reviewing; this strand has had concurrent work in the same files
|
|
112
|
-
throughout.
|
|
113
|
-
|
|
114
|
-
### Required tests to WRITE
|
|
115
|
-
|
|
116
|
-
1. **Non-vacuity:** a fixture source with `<Paper sx={{ borderColor: 'divider' }}>` against a theme
|
|
117
|
-
whose `MuiPaper` already sets `borderColor: divider` produces a finding naming the file, line,
|
|
118
|
-
component and property.
|
|
119
|
-
2. **The legitimate case produces nothing:** the same fixture with a *different* value
|
|
120
|
-
(`borderColor: 'error.main'`) is **not** flagged. This is the test that keeps the check usable.
|
|
121
|
-
3. A component the theme does not style is not flagged at all.
|
|
122
|
-
4. The finding shape matches its siblings, so a consumer handles one contract.
|
|
123
|
-
5. `reportOffPaletteColours` is unchanged — its existing tests stay green untouched.
|
|
124
|
-
|
|
125
|
-
Plus `tsc -p tsconfig.build.json --noEmit` clean. **No full-suite run** — affected set is the theme
|
|
126
|
-
module's specs.
|
|
127
|
-
|
|
128
|
-
### Verification
|
|
129
|
-
|
|
130
|
-
No rendered surface. The evidence is test 1 plus the cockpit count, reported in the register note with
|
|
131
|
-
the exact number and a sample of what it found. A check nobody has run against real code is not
|
|
132
|
-
verified, however green its fixtures.
|
|
133
|
-
|
|
134
|
-
### Parity guardrail
|
|
135
|
-
|
|
136
|
-
Nothing renders differently. No existing check changes behaviour.
|
|
137
|
-
|
|
138
|
-
---
|
|
139
|
-
|
|
140
|
-
## B. Implementation map
|
|
141
|
-
|
|
142
|
-
*Filled by the Orchestrator on `git pull` — see `AGENTS.md` → "Work Order".*
|
|
143
|
-
|
|
144
|
-
### Execution directive (read this first)
|
|
145
|
-
|
|
146
|
-
> **If you are the implementer reading this work order as your own specification: this section is
|
|
147
|
-
> NOT addressed to you.** It tells the Orchestrator how to invoke you. **You ARE that invocation —
|
|
148
|
-
> do NOT shell out to `codex exec`.**
|
|
149
|
-
>
|
|
150
|
-
> Implement through `codex exec` in the background — invoked directly via Bash (never the
|
|
151
|
-
> `debugger`/`*_coder` Agent wrappers) with BOTH flags `--skip-git-repo-check` and
|
|
152
|
-
> `--dangerously-bypass-approvals-and-sandbox`. **Pass the WO via stdin, not as a positional
|
|
153
|
-
> argument.** Fallback to direct Claude implementation only on Codex quota/rate-limit/non-zero exit —
|
|
154
|
-
> and that flips authorship, so the independent `reviewer` stays mandatory either way.
|
|
155
|
-
>
|
|
156
|
-
> **Do NOT edit `WORK_ORDERS.md`.** Before your own review read `git log origin/main..HEAD` and
|
|
157
|
-
> `git status`, and check the register row carries no review claim you did not make yourself.
|
|
158
|
-
|
|
159
|
-
### Context package
|
|
160
|
-
|
|
161
|
-
**Precondition confirmed:** `SHELL-6` landed and published (`f119b70`/`3b746d4`, `package.json` reads
|
|
162
|
-
`2.37.1`). Clean starting tree.
|
|
163
|
-
|
|
164
|
-
**Reusable primitives already in `src/theme/themeCompleteness.js` — do not rebuild these:**
|
|
165
|
-
- `getPath(value, path)` (`:13-15`) and `sameValue(left, right)` (`:17-21`) — exactly what "resolve
|
|
166
|
-
what the theme gives for that property and flag equality" needs; both already handle the
|
|
167
|
-
string/JSON-stringify comparison this check requires.
|
|
168
|
-
- `BASELINE_STYLED_MUI_COMPONENTS` (`:484-508`, 23-entry list), `jsxOpeningTag(source, start)`
|
|
169
|
-
(`:510-530`, returns the full `<Tag ...>` text starting at a match) and `topLevelSxValue(tag)`
|
|
170
|
-
(`:532-553`, extracts the raw `sx={...}` attribute text, top-level braces only) — the exact
|
|
171
|
-
tag-scanning machinery `reportKitSxBypasses` (`:560-`) already uses. Reuse the same
|
|
172
|
-
`<(${componentPattern})\\b` regex approach for finding tags; you will need a NEW small parser to
|
|
173
|
-
walk `topLevelSxValue`'s result and extract individual top-level `property: value` pairs from a
|
|
174
|
-
literal object (`{ borderColor: 'divider', p: 2 }` → `[['borderColor', "'divider'"], ['p', '2']]`) —
|
|
175
|
-
this doesn't exist yet, write it narrowly (top-level only, matching the existing lower-bound
|
|
176
|
-
philosophy; do not attempt to parse nested objects, media-query keys, or `theme =>` callbacks).
|
|
177
|
-
- `reportOffPaletteColours`'s `normalizedSources`/path-skip pattern (`:747-753`, `:768-769`) — same
|
|
178
|
-
`{ path, source }` input shape, reuse `normalizedSources` directly, do NOT touch or widen its
|
|
179
|
-
`/(^|\/)src\/theme\//` skip (Non-goal, explicit).
|
|
180
|
-
|
|
181
|
-
**A real discrepancy found while preparing this map, worth resolving deliberately rather than
|
|
182
|
-
silently — the WO's own "grounded in cockpit" evidence does not match its own stated attribution
|
|
183
|
-
method:** the cited `borderColor: 'divider'` (×2), `bgcolor: 'background.paper'` (×3, one is inside a
|
|
184
|
-
`'&:hover'` nested selector), and `borderRadius: 1` (×3) all live in
|
|
185
|
-
`cockpit/frontend/src/cockpit/ChatView.jsx:75,82,95`, on **`<Box component="button" sx={{...}}>`** —
|
|
186
|
-
verified directly, not assumed. `Box` is not in `BASELINE_STYLED_MUI_COMPONENTS`, and the WO's own
|
|
187
|
-
"Scope" section describes attribution purely by JSX tag name (`<Paper sx=...> → MuiPaper`), while its
|
|
188
|
-
own "bound" section separately, explicitly lists a component rendered through `component={...}` as a
|
|
189
|
-
KNOWN, ACCEPTED GAP. **These two things conflict**: the check as scoped will NOT catch the WO's own
|
|
190
|
-
cited grounding examples. Meanwhile, cockpit's actual `<Paper>`/`<Card>`/etc. usages elsewhere
|
|
191
|
-
(`HeaderStrip.jsx`, `KnowledgeView.jsx`, `SettingsView.jsx`, and others) mostly use **template-literal**
|
|
192
|
-
sx values like `` border: `1px solid ${palette.divider}` `` — a JS expression referencing cockpit's own
|
|
193
|
-
imported `palette` object, not a plain string literal — which a source-level literal-value parser also
|
|
194
|
-
cannot resolve to "equals the theme's value" without evaluating arbitrary JS.
|
|
195
|
-
|
|
196
|
-
**Resolve this by NOT expanding scope to chase the cited numbers** (that would be exactly the
|
|
197
|
-
"enumeration reads as coverage" mistake the WO warns against, applied to attribution instead of the
|
|
198
|
-
bound's phrasing) — implement the check exactly as scoped (tag-name attribution, literal `'string'`/
|
|
199
|
-
`"string"`/numeric sx values only, skip anything that isn't a simple literal — a template literal,
|
|
200
|
-
identifier reference, or expression is out of scope and simply produces no finding for that property,
|
|
201
|
-
same lower-bound philosophy as every sibling check). **Then, when running it against cockpit for the
|
|
202
|
-
required count and sample, report what it ACTUALLY finds — which may be zero, or may differ from the
|
|
203
|
-
Envelope's cited 2+3+3 — and say so explicitly in the register note as a correction to the Envelope's
|
|
204
|
-
own grounding claim**, the same way prior WOs in this strand corrected their own stale counts
|
|
205
|
-
(`THEME-4`'s "51 files", `SHELL-4`'s "ten to six"). Do not silently match the cited numbers by quietly
|
|
206
|
-
special-casing `component=` or template-literal parsing to make them fit — if the honest run finds
|
|
207
|
-
different examples (or none) on properly-attributable tags, that is the real, reportable result.
|
|
208
|
-
|
|
209
|
-
**Where to add the new export:** same file, `src/theme/themeCompleteness.js`, alongside its siblings.
|
|
210
|
-
Suggested name (Codex's call, keep it short and consistent with `reportKitSxBypasses`/
|
|
211
|
-
`reportOffPaletteColours`): `reportRedundantThemeValues` or `reportAppSxRedundancy`. Same
|
|
212
|
-
`{ findings: [{ surface, reason }] }` contract; `surface` should follow the sibling convention
|
|
213
|
-
(`${path}:${line}.${property}` or similar — check `reportOffPaletteColours`'s `${path}:${line}.colour`
|
|
214
|
-
shape for the exact precedent). Export it from `src/theme/index.js` and `src/index.js` (follow the
|
|
215
|
-
existing export-list pattern in both — this is additive public API, matching the "next minor" version
|
|
216
|
-
target).
|
|
217
|
-
|
|
218
|
-
**Signature, per Scope item 1 + 2:** `reportRedundantThemeValues(sources, { theme })` — takes the
|
|
219
|
-
app's own sources (same `{path, source}`/string-array shape as siblings) and a **resolved theme
|
|
220
|
-
object** (an app passes its own `createAppTheme(...)` result, or — for ucm's own required tests — a
|
|
221
|
-
theme built the same way `assertKitSxDisjoint`'s tests do). For each JSX tag matching
|
|
222
|
-
`BASELINE_STYLED_MUI_COMPONENTS`, for each top-level literal `property: value` pair in its `sx`,
|
|
223
|
-
resolve `theme.components.Mui<Tag>.styleOverrides.root.<property>` via `getPath` and flag if
|
|
224
|
-
`sameValue(parsedValue, themeValue)` — matching value AND matching property AND matching component,
|
|
225
|
-
report-only (no exemption arm needed per the WO — this ships report-only with no hard-assertion path
|
|
226
|
-
yet, so skip building an exemption contract this round, that's each app's own future ratchet WO).
|
|
227
|
-
|
|
228
|
-
**Running it against cockpit (Scope item 3, required for the register note):** cockpit's frontend
|
|
229
|
-
source lives at `C:\Users\biglmi\Documents\webapps\cockpit\frontend\src` (37 `.jsx` files, confirmed).
|
|
230
|
-
Glob it (a small Node script or a throwaway test-like harness is fine — this does not need to be a
|
|
231
|
-
committed cockpit-side test, just evidence for the register note) the same way `reportOffPaletteColours`'s
|
|
232
|
-
own `'keeps current kit source free of hard off-palette findings'` test globs `src/` — exclude
|
|
233
|
-
`cockpit/frontend/src/theme.js` explicitly from the sources passed (per Scope's "resolve it app-side"
|
|
234
|
-
instruction — do NOT widen `reportOffPaletteColours`'s or this new check's own skip pattern to do it).
|
|
235
|
-
Build the theme via cockpit's own `createAppTheme(...)` call if one exists (check `theme.js` for the
|
|
236
|
-
palette it passes), or a reasonable equivalent. Report the exact count and 2-3 sample findings in the
|
|
237
|
-
register note, per Verification's explicit requirement — a check nobody has run against real code is
|
|
238
|
-
not verified.
|
|
239
|
-
|
|
240
|
-
**Invariants:** no fix in cockpit or the kit; no change to `reportOffPaletteColours`,
|
|
241
|
-
`assertKitSxDisjoint`, `reportKitSxBypasses`, `reportThemeAdoption`, or `assertThemeComplete`; no new
|
|
242
|
-
baseline token; no hard assertion anywhere (report-only only).
|
|
243
|
-
|
|
244
|
-
### Mini-handover
|
|
245
|
-
|
|
246
|
-
Repo: `ui-core-micha` (`C:\Users\biglmi\Documents\webapps\ui-core-micha`), branch `main`.
|
|
247
|
-
WO: `work-orders/THEME-6.md`. Follow `orchestrate-codex`.
|
package/work-orders/THEME-7.md
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
# THEME-7 — Guidance: a series slot that collides with an app's own accent
|
|
2
|
-
|
|
3
|
-
## Part A — Envelope
|
|
4
|
-
|
|
5
|
-
**Goal.** Give consuming apps a documented answer for the case where a baseline
|
|
6
|
-
`dataSeries.categorical` slot sits too close to something the app itself owns — the app's
|
|
7
|
-
accent, or one of its domain identity colours. Today the baseline offers six series colours
|
|
8
|
-
and no guidance for that collision, so each app rediscovers the problem on its own.
|
|
9
|
-
|
|
10
|
-
**Why — a measured case, not a hypothesis.** During hram's Imara design-language work
|
|
11
|
-
(hram `IMARA-2`, frozen 2026-08-13) two collisions were measured against the app's own
|
|
12
|
-
values, using Lab ΔE with the operator's own rejected candidate pair as the calibration
|
|
13
|
-
floor (that pair sat at ΔE 16.6 and was judged "not tellable apart"):
|
|
14
|
-
|
|
15
|
-
- baseline series 1 `#3D5A99` versus hram's chosen primary `#2F4F96` → **ΔE 7.2**, the
|
|
16
|
-
tightest pair in that app's whole system; a series line beside a primary button reads as
|
|
17
|
-
the same colour.
|
|
18
|
-
- baseline series 3 `#2E8F8A` versus hram's DALYs identity `#1F7A72` → **ΔE 8.3**; same
|
|
19
|
-
hue (a −28.7 vs −27.8), one lightness step apart (L 54 vs 46).
|
|
20
|
-
|
|
21
|
-
hram resolved both app-side: slot 1 dropped entirely (both replacement candidates measured
|
|
22
|
-
worse elsewhere — a neutral slate landed ΔE 5.0 from the shared `stale` fill, a muted green
|
|
23
|
-
ΔE 15.5 from the app's own olive slot), and slot 3 replaced by a navy, which simultaneously
|
|
24
|
-
restored the dark blue the first removal had taken away. The nine remaining slots plus an
|
|
25
|
-
overflow grey covered the app's needs.
|
|
26
|
-
|
|
27
|
-
**This is not a defect report against the baseline.** For an app whose primary is not a
|
|
28
|
-
muted indigo and which has no teal domain identity, series 1 and 3 are correct and useful.
|
|
29
|
-
What is missing is the *guidance*, and the observation that the baseline's own muted,
|
|
30
|
-
cool-leaning character makes a collision with a tastefully chosen accent more likely rather
|
|
31
|
-
than less — apps that like this palette tend to pick accents from the same region.
|
|
32
|
-
|
|
33
|
-
**Scope.**
|
|
34
|
-
|
|
35
|
-
1. `DESIGN.md` — a short subsection under the data-colour principle: how to check a chosen
|
|
36
|
-
accent against the series palette (measure, do not eyeball; a usable threshold with the
|
|
37
|
-
calibration above named as its provenance), and what to do when it collides — drop the
|
|
38
|
-
slot rather than nudge it, because a nudged slot stays confusable while a dropped one is
|
|
39
|
-
simply absent.
|
|
40
|
-
2. The same note in the theme package's own documentation where `dataSeries.categorical` is
|
|
41
|
-
described, so it is found by someone reading the token rather than the design doc.
|
|
42
|
-
3. **Decide and record**: whether the baseline should additionally *ship* anything —
|
|
43
|
-
candidates being an exported ΔE helper apps can assert with, a documented extension
|
|
44
|
-
sequence for apps needing more than six slots, or nothing at all beyond the guidance.
|
|
45
|
-
Doing nothing is a legitimate outcome and should be recorded as a decision if chosen.
|
|
46
|
-
|
|
47
|
-
**Non-goals / do-not-touch.** Do **not** change the six shipped series values — hram's
|
|
48
|
-
divergence is app-specific and other consumers depend on the current set. No change to the
|
|
49
|
-
status palette, the completeness assertion, or any component. This is documentation plus,
|
|
50
|
-
at most, one small additive export.
|
|
51
|
-
|
|
52
|
-
**Tier 3** — shared-core surface, per the estate tiering table, even though the change is
|
|
53
|
-
documentation-led. Independent review mandatory.
|
|
54
|
-
|
|
55
|
-
**Tests to write.** None for the documentation. If item 3 lands a helper, that helper gets
|
|
56
|
-
its own unit test with the two measured pairs above as fixtures — they are real values with
|
|
57
|
-
known answers.
|
|
58
|
-
|
|
59
|
-
**Risks.** The guidance is derived from a single app's experience; state that plainly rather
|
|
60
|
-
than presenting it as a general law. The threshold in particular is calibrated on one
|
|
61
|
-
operator's judgement — useful as a starting point, not as a standard, and it should say so.
|
|
62
|
-
|
|
63
|
-
## Part B — Implementation map (implementer)
|
|
64
|
-
|
|
65
|
-
PLACEHOLDER — Orchestrator fills this on `git pull`: context package with `path:line`
|
|
66
|
-
anchors into `DESIGN.md` and the token documentation, the absolute working directory, the
|
|
67
|
-
progress contract, the preamble. Not dispatchable while this stands.
|
|
68
|
-
|
|
69
|
-
## Part C — Orchestrator only
|
|
70
|
-
|
|
71
|
-
**STOP — addressee guard.** If you are the implementer reading this file as your own spec:
|
|
72
|
-
this part is not addressed to you. It tells the Orchestrator how to invoke you; you ARE that
|
|
73
|
-
invocation — do not shell out to `codex exec`. Stop reading at this line.
|
|
74
|
-
|
|
75
|
-
- **Execution.** Codex first per the Tier-2/3 rule unless the status record says otherwise.
|
|
76
|
-
- **Review routing.** `reviewer` mandatory (Tier 3). No `ui_reviewer` unless item 3 turns
|
|
77
|
-
into code with a visual surface, which it should not.
|
|
78
|
-
- **Verification.** Scoped: the theme package's existing tests must stay green; any new
|
|
79
|
-
helper carries its own.
|
|
80
|
-
- **Cross-repo.** Reference hram `IMARA-2` and its frozen sheet as the evidence source; do
|
|
81
|
-
not restate the measurements from memory when the artifact holds them.
|
|
82
|
-
|
package/work-orders/THEME-8.md
DELETED
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
# THEME-8 — The select touch target sits on the wrong element and pushes its text off-centre
|
|
2
|
-
|
|
3
|
-
## Part A — Envelope
|
|
4
|
-
|
|
5
|
-
**Goal.** Move the baseline's touch-target minimum height for `MuiSelect` from the inner
|
|
6
|
-
`select` slot to the input root, so the existing flex centring can do its job. Every
|
|
7
|
-
consuming app's select text is currently top-anchored instead of vertically centred.
|
|
8
|
-
|
|
9
|
-
**Why — measured, not inferred.** `src/theme/tokens.js` sets
|
|
10
|
-
|
|
11
|
-
```js
|
|
12
|
-
MuiSelect: { styleOverrides: { select: {
|
|
13
|
-
minHeight: 40,
|
|
14
|
-
'@media (any-pointer: coarse)': { minHeight: 44 },
|
|
15
|
-
} } }
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
`.MuiSelect-select` is the element that carries MUI's variant-dependent padding, and for
|
|
19
|
-
the `standard` variant that padding is deliberately top-anchored (`1px 24px 5px 0`). Forcing
|
|
20
|
-
a 40/44 px height onto a `display: block` element whose content needs ~26 px puts the whole
|
|
21
|
-
surplus below the text, so the text rides high in its box.
|
|
22
|
-
|
|
23
|
-
Measured live in a consuming app (hram, Administration → Users, a select inside a table
|
|
24
|
-
cell), then verified by moving the rule to the root at runtime:
|
|
25
|
-
|
|
26
|
-
| | space above the text | space below |
|
|
27
|
-
|---|---|---|
|
|
28
|
-
| today | 0 px | 0 px — inner stretched to 44 px, top-anchored |
|
|
29
|
-
| min-height on the root instead | **9 px** | **9 px** |
|
|
30
|
-
|
|
31
|
-
The root (`MuiInputBase-root`) is already `display: flex; align-items: center`, so it centres
|
|
32
|
-
the natural-height inner element for free.
|
|
33
|
-
|
|
34
|
-
**This is an inconsistency inside the baseline, not a design choice.** Of the six components
|
|
35
|
-
that carry a touch target — `MuiButton`, `MuiIconButton`, `MuiSelect`, `MuiCheckbox`,
|
|
36
|
-
`MuiFormControlLabel`, `MuiTextField` — **`MuiSelect` is the only one that targets a
|
|
37
|
-
non-root slot.** The other five all use `root`.
|
|
38
|
-
|
|
39
|
-
**Amplified on touch-capable machines.** The `@media (any-pointer: coarse)` branch raises it
|
|
40
|
-
to 44 px, and a laptop with a touchscreen matches that query. The operator's machine reports
|
|
41
|
-
`any-pointer: coarse`, which is why it looks worse there than on a non-touch machine — the
|
|
42
|
-
same defect, 4 px larger.
|
|
43
|
-
|
|
44
|
-
**Scope.**
|
|
45
|
-
|
|
46
|
-
1. Move the minimum height off `styleOverrides.select` and onto the root, keeping both the
|
|
47
|
-
base value and the coarse-pointer branch. **Verify which root actually receives it** —
|
|
48
|
-
`MuiSelect`'s `root` slot composes with the underlying input, and the outlined and
|
|
49
|
-
standard variants compose differently; if `MuiSelect.root` does not carry it cleanly for
|
|
50
|
-
both, `MuiInputBase.root` is the alternative. Decide by measuring in a running app, not
|
|
51
|
-
by reading the MUI source.
|
|
52
|
-
2. Check the outlined variant does not grow taller than a neighbouring `MuiTextField` after
|
|
53
|
-
the move — `MuiTextField` already carries its own root min-height, so the two must still
|
|
54
|
-
line up in a form row.
|
|
55
|
-
3. A test that pins the intent: assert the minimum height is not applied to the `select`
|
|
56
|
-
slot (or, better, assert the rendered inner element's natural height is preserved). A
|
|
57
|
-
test that only checks "44 px somewhere" would pass on the broken version too.
|
|
58
|
-
|
|
59
|
-
**Non-goals / do-not-touch.** Do not change the touch-target *value* (40 / 44) — the size is
|
|
60
|
-
correct, only its anchor is wrong. Do not touch the other five components; they are already
|
|
61
|
-
correct. No colour, typography or density changes. Do not "fix" this per-app with an sx
|
|
62
|
-
override in a consumer — that is what this baseline exists to prevent.
|
|
63
|
-
|
|
64
|
-
**Tier 3** — shared-core surface. `reviewer` mandatory. Every consuming app's selects change
|
|
65
|
-
appearance (for the better), which is exactly why it belongs here rather than in one app.
|
|
66
|
-
|
|
67
|
-
**Tests to write.** The intent test above, plus whatever existing theme/completeness suite
|
|
68
|
-
covers component overrides. Keep it small; the real proof is the rendered measurement.
|
|
69
|
-
|
|
70
|
-
**Risks.**
|
|
71
|
-
- **Estate-wide visual change.** Every app using the baseline gets subtly taller-looking
|
|
72
|
-
select rows or re-centred text. That is the fix, but it will be visible in apps nobody is
|
|
73
|
-
currently working on — name it in the release notes rather than letting it surprise someone.
|
|
74
|
-
- Moving a min-height between slots can change how a select aligns next to a text field in
|
|
75
|
-
the same row. Scope item 2 exists for that; check it in a real form, not in isolation.
|
|
76
|
-
- The coarse-pointer branch means a reviewer on a non-touch machine sees 40 px and a milder
|
|
77
|
-
version of the defect. Say which machine the verification ran on.
|
|
78
|
-
|
|
79
|
-
**Delivery is not done at publish.** A version bump alone does not fix any app. The
|
|
80
|
-
consuming apps still need their pin bumped and a look at their own forms — hram in
|
|
81
|
-
particular, where this was found. Track the consumer bumps rather than closing this WO at
|
|
82
|
-
the npm publish.
|
|
83
|
-
|
|
84
|
-
## Part B — Implementation map — ADDRESSED TO THE IMPLEMENTER
|
|
85
|
-
|
|
86
|
-
### Context package
|
|
87
|
-
|
|
88
|
-
**Named file to change:** `src/theme/tokens.js`, the `MuiSelect` block, currently:
|
|
89
|
-
|
|
90
|
-
```js
|
|
91
|
-
MuiSelect: {
|
|
92
|
-
defaultProps: { variant: 'outlined' },
|
|
93
|
-
styleOverrides: {
|
|
94
|
-
select: {
|
|
95
|
-
minHeight: 40,
|
|
96
|
-
boxSizing: 'border-box',
|
|
97
|
-
'@media (any-pointer: coarse)': { minHeight: 44 },
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
},
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
(around `src/theme/tokens.js:255-264`). The shared coarse-pointer helper used by every other
|
|
104
|
-
component sits just above it:
|
|
105
|
-
|
|
106
|
-
```js
|
|
107
|
-
const coarseHitArea = {
|
|
108
|
-
'@media (any-pointer: coarse)': {
|
|
109
|
-
minHeight: 44,
|
|
110
|
-
minWidth: 44,
|
|
111
|
-
},
|
|
112
|
-
};
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
(`src/theme/tokens.js:135-140`). The five correct comparators, for the target shape (all use
|
|
116
|
-
`styleOverrides.root` and the shared `coarseHitArea` spread):
|
|
117
|
-
|
|
118
|
-
- `MuiButton` — `src/theme/tokens.js:233-245` (`root: { minHeight: 40, ..., ...coarseHitArea }`)
|
|
119
|
-
- `MuiIconButton` — `:249-251`
|
|
120
|
-
- `MuiCheckbox` — `:265-267`
|
|
121
|
-
- `MuiFormControlLabel` — `:268-273`
|
|
122
|
-
- `MuiTextField` — `:334-337`
|
|
123
|
-
|
|
124
|
-
Also relevant: `MuiOutlinedInput` already sets `root: { minHeight: 40, ...coarseHitArea }`
|
|
125
|
-
(`:338-346`) — since `MuiSelect` with `variant: 'outlined'` (the default here) composes with
|
|
126
|
-
`MuiOutlinedInput`'s root, moving `MuiSelect`'s own min-height onto `MuiSelect.styleOverrides.root`
|
|
127
|
-
must not double up with that existing rule for the outlined variant. Measure both variants
|
|
128
|
-
(`outlined` default, and `standard` where used) in a running app before deciding whether the
|
|
129
|
-
target is `MuiSelect.styleOverrides.root` or `MuiInputBase.styleOverrides.root` — the Envelope
|
|
130
|
-
already flags this as a measure-don't-read decision.
|
|
131
|
-
|
|
132
|
-
**Second file:** `src/theme/themeCompleteness.js` references the old path and must move with it:
|
|
133
|
-
|
|
134
|
-
```
|
|
135
|
-
75: componentPath('MuiSelect', 'defaultProps.variant'),
|
|
136
|
-
76: componentPath('MuiSelect', 'styleOverrides.select.minHeight'),
|
|
137
|
-
77: componentKeyLeaf('MuiSelect', 'styleOverrides.select', '@media (any-pointer: coarse)', 'minHeight'),
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
Update lines 76-77 to point at wherever the min-height actually lands (`styleOverrides.root...`
|
|
141
|
-
or `styleOverrides.select` removed entirely if the property is dropped from that slot) — keep
|
|
142
|
-
line 75 (`defaultProps.variant`) as is, it is unrelated. This file drives the baseline's own
|
|
143
|
-
completeness assertion; a stale path here makes the completeness suite pass against dead code.
|
|
144
|
-
|
|
145
|
-
**Existing test suite for reference:** `tests/themeCompleteness.test.js` — no existing test
|
|
146
|
-
references `MuiSelect` by name today, so the new intent test (Envelope scope item 3) is net new,
|
|
147
|
-
not a modification of an existing case.
|
|
148
|
-
|
|
149
|
-
**Invariants / do-not-touch:** the touch-target *value* stays 40 / 44 — only the slot changes.
|
|
150
|
-
Do not touch `MuiButton`, `MuiIconButton`, `MuiCheckbox`, `MuiFormControlLabel`, `MuiTextField`,
|
|
151
|
-
or `MuiOutlinedInput` beyond what's needed to avoid the double-application noted above. No
|
|
152
|
-
colour/typography/density changes anywhere in this diff.
|
|
153
|
-
|
|
154
|
-
Directive: work from this package; do not explore broadly from scratch; open only the named
|
|
155
|
-
files to verify. If you must dig deeper, delegate to a read-only Explore sub-agent (Haiku).
|
|
156
|
-
|
|
157
|
-
### Target repo working directory (absolute)
|
|
158
|
-
|
|
159
|
-
`C:\Users\biglmi\Documents\webapps\ui-core-micha`
|
|
160
|
-
|
|
161
|
-
### Preamble — REQUIRED, addressed to the implementer
|
|
162
|
-
|
|
163
|
-
> The text above is the COMPLETE spec — the committed WO file's content, not a plan to refine;
|
|
164
|
-
> there is no separate plan file. Read the nearest `AGENTS.md`, the relevant
|
|
165
|
-
> `.codex/skills/<role>/SKILL.md`, and the app `MEMORY.md` ONLY for conventions. Stay in scope;
|
|
166
|
-
> do not touch auth/permissions/deps/schema/CI unless the spec says so; do not update
|
|
167
|
-
> `MEMORY.md`. **Do NOT edit `WORK_ORDERS.md`** — the register row and the review verdicts are
|
|
168
|
-
> the orchestrator's alone. Do NOT `git add`/`commit`/`push` — leave every change uncommitted in
|
|
169
|
-
> the working tree for the orchestrator's independent review. WRITE the tests the "Required
|
|
170
|
-
> tests" section (Part A) calls for AND **RUN the tests you just wrote** to confirm they execute
|
|
171
|
-
> and pass — that is the ONLY test run you do (NOT the app's affected/full suite, NOT any
|
|
172
|
-
> review). The orchestrator re-runs the authoritative set + does the independent review after
|
|
173
|
-
> you finish — those are the gate; your own run does not count as the gate.
|
|
174
|
-
>
|
|
175
|
-
> Narrate continuously: a `PLAN: <step1> | <step2> | …` line up front, then a single-line
|
|
176
|
-
> `PROGRESS: [<n>/<total>] <present-tense action>` before every relevant action (and `… done` on
|
|
177
|
-
> completion), spaced so no gap exceeds ~2 min, stdout unbuffered, plus exactly one final
|
|
178
|
-
> `RESULT: DONE|BLOCKED <reason>`.
|
|
179
|
-
|
|
180
|
-
## Part C — Orchestrator only — NOT ADDRESSED TO THE IMPLEMENTER
|
|
181
|
-
|
|
182
|
-
> **If you are the implementer reading this work order as your own specification: STOP at this
|
|
183
|
-
> line. Everything below describes what the Orchestrator does AFTER you finish. You do none of
|
|
184
|
-
> it — no reviewers, no verification run, no register edit, no commit.** You ARE the invocation
|
|
185
|
-
> described below; do NOT shell out to `codex exec`.
|
|
186
|
-
|
|
187
|
-
## Execution directive
|
|
188
|
-
|
|
189
|
-
Implement through `codex exec` in the background — invoked directly via Bash (never the
|
|
190
|
-
`debugger`/`*_coder` Agent wrappers) with BOTH flags `--skip-git-repo-check` and
|
|
191
|
-
`--dangerously-bypass-approvals-and-sandbox`. Fallback to direct Claude implementation only on
|
|
192
|
-
Codex quota/rate-limit/non-zero exit — the fallback flips authorship, so an independent
|
|
193
|
-
`reviewer` becomes mandatory (already required at Tier 3, so no incremental change there).
|
|
194
|
-
|
|
195
|
-
## Review routing
|
|
196
|
-
|
|
197
|
-
`reviewer` mandatory (Tier 3); `ui_reviewer` too, since the visible result is a layout change
|
|
198
|
-
across every consumer. Both spawned in the same background batch, Sonnet-pinned (Tier 3), diff
|
|
199
|
-
inline, pointed at this WO's Envelope only.
|
|
200
|
-
|
|
201
|
-
## Verification
|
|
202
|
-
|
|
203
|
-
The package's own suite (`tests/themeCompleteness.test.js` plus the new intent test), plus a
|
|
204
|
-
**rendered check in a consuming app**: a select in a table row and a select beside a text field,
|
|
205
|
-
both re-measured for equal space above and below the text. State which machine (coarse or fine
|
|
206
|
-
pointer) the measurement ran on.
|
|
207
|
-
|
|
208
|
-
## Register + commit
|
|
209
|
-
|
|
210
|
-
Advance the THEME-8 row with the named reviewer verdicts and the measured before/after numbers.
|
|
211
|
-
Then track the consumer pin bumps (hram first) — this WO is not done at npm publish.
|