@micha.bigler/ui-core-micha 3.1.0 → 3.1.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 +59 -0
- package/WORK_ORDERS.md +20 -1
- package/dist/components/charts/ChartFrame.js +18 -9
- package/docs/CHART-LAYOUT.md +9 -3
- package/package.json +1 -1
- package/scripts/chart-api-census.mjs +407 -0
- package/src/components/charts/ChartFrame.jsx +19 -10
- package/tests/ChartFrame.test.jsx +30 -7
- package/tests/chart-api-census.test.js +366 -0
- package/work-orders/UCM-CHART-14.md +198 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Only notable, user-facing changes. Not every version — see `WORK_ORDERS.md` for the full history.
|
|
4
|
+
|
|
5
|
+
## 3.1.1 — UCM-CHART-14
|
|
6
|
+
|
|
7
|
+
**Corrects a wrong record from `3.1.0`, and a runtime error message that stated the opposite of
|
|
8
|
+
what actually happened. No API change in this version.**
|
|
9
|
+
|
|
10
|
+
`3.1.0` (`UCM-CHART-13`) removed `ChartFrame`'s `height` and `aspect` props, and claimed — in the
|
|
11
|
+
docblock, in `docs/CHART-LAYOUT.md`, and in the commit message — that no consumer passed `aspect`.
|
|
12
|
+
**That measurement was false.** A parser-based census (`scripts/chart-api-census.mjs`, ground truth
|
|
13
|
+
over a `head`-truncated grep that had missed them) found **four live call sites in
|
|
14
|
+
fitness-monitor** (`BodyHistoryPage.jsx` ×2, `EnvironmentPage.jsx` ×2) that do pass `aspect`, and
|
|
15
|
+
whose cards visibly change shape once `3.1.0`+ is adopted — `aspect` was genuinely applied
|
|
16
|
+
(`aspectRatio` on the card box) through `3.0.1`, not a no-op.
|
|
17
|
+
|
|
18
|
+
**The removal itself is not reverted** — the operator confirmed this stands. What changes here:
|
|
19
|
+
|
|
20
|
+
- The dev-mode error `<ChartFrame>` throws when a caller still passes `aspect` no longer claims the
|
|
21
|
+
prop "was never applied". It now says plainly that it WAS applied, that this is a real visible
|
|
22
|
+
change, and that `size` on the chart inside the frame is the replacement if a chart's own height
|
|
23
|
+
was meant.
|
|
24
|
+
- The false "no consumer passes it" claim is corrected — not deleted — everywhere it shipped
|
|
25
|
+
(`ChartFrame.jsx`'s docblock, `docs/CHART-LAYOUT.md`, `tests/ChartFrame.test.jsx`'s comment) so
|
|
26
|
+
the record shows what was measured, both times.
|
|
27
|
+
- A new dev script, `scripts/chart-api-census.mjs`, parses (does not grep) every sibling repo's use
|
|
28
|
+
of the four chart presets and `ChartFrame`, reporting exactly which of `aspect`/`height`/
|
|
29
|
+
`minHeight`/`margin`/`xAxisAngle` each call site still carries, with file:line. Not part of the
|
|
30
|
+
package's runtime surface — a workspace-local tool for the next migration WO.
|
|
31
|
+
|
|
32
|
+
**This is a patch, not a major**, even though an applied prop was removed: no consumer has crossed
|
|
33
|
+
`3.1.0` yet (hram is on `3.0.1`, fitness-monitor on `3.0.1` in its working tree, jg-ferien on
|
|
34
|
+
`2.41.1`), and the break is not silent — `assertRemovedChartProp` throws in dev at the exact call
|
|
35
|
+
site, which is what a major version's "read the release notes" warning exists to approximate in the
|
|
36
|
+
first place. Migrating fitness-monitor's four call sites is `FM-CHART-1`'s scope, not this one's.
|
|
37
|
+
|
|
38
|
+
## 3.1.0 — UCM-CHART-13
|
|
39
|
+
|
|
40
|
+
`ChartFrame` no longer accepts `height` or `aspect` — only `minHeight` (the card floor) is applied.
|
|
41
|
+
Both now throw a dev-mode error naming the replacement. See `3.1.1` above for a correction to this
|
|
42
|
+
version's own release notes.
|
|
43
|
+
|
|
44
|
+
## 3.0.1 — UCM-CHART-12 (fix round)
|
|
45
|
+
|
|
46
|
+
Follow-up fixes to `3.0.0`'s chart layout model after a second, independent review round: a
|
|
47
|
+
secondary (right-positioned) y-axis's width is now accounted for, `xLabels="auto"` decides rotation
|
|
48
|
+
from the label's real measured width rather than a character count, a blank-formatted y-axis
|
|
49
|
+
collapses its reserved band to zero the same way the x-axis case does, and the resolver now reserves
|
|
50
|
+
space for wherever a legend actually renders (`slotProps.legend.position`), not just the
|
|
51
|
+
`legendPosition` prop alone.
|
|
52
|
+
|
|
53
|
+
## 3.0.0 — UCM-CHART-12
|
|
54
|
+
|
|
55
|
+
**Breaking.** One layout model replaces the chart presets' `minHeight`/`height`/`aspect`/`margin`/an
|
|
56
|
+
implicit rotation prop with `resolveChartLayout`, driven by `size`
|
|
57
|
+
(`"compact"`|`"standard"`|`"tall"`, + a `height` px escape) and `xLabels`
|
|
58
|
+
(`"auto"`|`"horizontal"`|`"angled"`). Every reserved band now derives from its own content and
|
|
59
|
+
collapses to zero when empty. See `docs/CHART-LAYOUT.md` for the full migration guide.
|
package/WORK_ORDERS.md
CHANGED
|
@@ -95,4 +95,23 @@ Two chunks. **Chunk 1** (Part 1 + Part 2 of the Envelope): extended `SPACING_SHO
|
|
|
95
95
|
| UCM-CHART-10 | The rotated-tick allowance is reserved twice, and the surplus is dead space | `spaceForRotatedTicks` adds the same `extraHeight` BOTH to `axis.height` and to `margin.bottom`, and in MUI v8 those are additive. The axis band already holds the rotated labels, so the margin copy is left over as an empty band below the plot. Measured in hram 2026-08-22 at 1280 px with ucm 2.42.1: Ward Metrics and Access Ladder each show a 340 px surface whose plot ends at 131 px -- **130 px, 38 %, empty**; Cost 92 px; Division Metrics 85 px; Cost-effectiveness 44 px; Expert Mode only 8 px. Two things make it conclusive: the band SCALES WITH THE LABEL LOAD (35 long rotated ward names cost 130 px, short labels cost 8), and `emptyBelowLowestLabel` equals `emptyBelowAxisLine` on every chart -- the labels sit inside the axis band and nothing occupies the space beneath them. | 2026-08-22 | done | 2026-08-22: `spaceForRotatedTicks` fix + version bump | Tier 3, shared-core. Full order: [`work-orders/UCM-CHART-10.md`](work-orders/UCM-CHART-10.md). THIRD instance of one failure class in this file: space reserved in two places that add up -- after UCM-CHART-8 (`minHeight` vs `height`) and hram's RES-28 (`margin.left` vs an unsized `yAxis`). Neither CHART-8 nor CHART-9 could have caught it: both worked on the wrapper BOX, this is the axis MARGIN arithmetic. **Fix:** kept `extraHeight` on `axis.height` only, `margin` now passes through `spaceForRotatedTicks` completely untouched (no `bottom` computed in any branch) -- a caller-set `margin.bottom` is therefore protected unconditionally, a strict superset of the removed `callerSetBottom` escape hatch, which both reviewers confirmed is a clean simplification, not a behaviour gap. **Codex:** `.claude/codex-status.md` already had an `unavailable` line for 2026-08-22 (logged during `UCM-CHART-9` earlier the same day) -- skipped the attempt per the known-unavailable shortcut, implemented directly, flipping authorship; `reviewer` + `ui_reviewer` were already mandatory at Tier 3, so no routing change. **Reviews:** `reviewer` and `ui_reviewer` ran concurrently (Sonnet, diff inline), both converged on the same two findings, both fixed before commit -- (1) version not bumped in-diff (fixed: `package.json` 2.42.1 -> 2.42.2, so `publish.yml`'s version-increase gate fires on push); (2) the WO's "investigate in the same pass" item (HRAM-RES-29 item 2, scatter x-axis tick-label clipping) had no recorded confirm/refute. **Refuted and recorded in the WO file:** `ScatterChart.jsx` never calls `spaceForRotatedTicks` at all, and hram's own named call sites (`AccessGapScatterPanel.jsx`, `OptimizationResultsPanel.jsx`) set no `tickLabelStyle.angle` either -- this helper cannot be the cause. Matches hram's own `HRAM-RES-29` register row, which had independently traced and closed item 2 the same day to an unrelated pre-2.42.0 missing-`height`-prop bug on `ScatterChart`, already fixed by `UCM-CHART-8`/2.42.0. Both reviews clean after fixes, no open findings. **Tests:** affected-area set (`chartDefaults` incl. new `spaceForRotatedTicks (CHART-10)` unit-test block, all four presets, `ChartFrame`) -- 134/134 green, preset assertions unchanged except the two that directly asserted the bug (rewritten to assert the fix, both reviewers confirmed the rewrite is correct and non-trivial). **Rendered check -- numeric, on hram with real data** (`CLI-Kilombero_2026-per_cell-network`, SG Sandbox CLI, same candidate point, Research -> Allocation -> Basic Plots), swapping the locally-built fixed `dist` into hram's `node_modules` for a live before/after (reverted after measurement, hram's own git tree untouched -- confirmed via `git status`): at 1280 px, Ward Metrics 129.6 px -> 51.6 px empty (35 labels, 340 px surface -- matches this row's own original 130 px/38% measurement almost exactly), Access Ladder 156.9 px -> 80.6 px (35 labels, 369 px), Division Metrics 85.2 px -> 41.2 px (5 labels, 340 px) -- each roughly halved, consistent with removing exactly one of two equal additive reservations. Checked again at 375 px: no clipping at either width, no regression. SUBSTITUTION DECLARED: screenshot capture was unavailable in this session (Browser pane would not composite frames) -- this is DOM/computed-style measurement (`getBoundingClientRect`/`getComputedStyle` against the live rendered SVG), which for this WO's numeric acceptance criterion is close to sufficient on its own, per the WO's own fallback clause. Cost/Cost-effectiveness/Expert Mode cards from the original six-card table were not individually re-measured (time-boxed after the first three -- Ward Metrics, Access Ladder, Division Metrics -- gave a clean, consistent, reviewer-confirmed signal); those three all use `BarChart` and its rotated-tick `xAxisAngle` path same as the measured cards (`CostMetricsPanel.jsx`, `RatioMetricsPanel.jsx` both call `spaceForRotatedTicks` via `BarChart`), so the fix is expected to reach them the same way, just not independently confirmed with numbers here. Publishes automatically via `publish.yml` on this push (version-increase gate). CONSUMER-SIDE CONFIRMATION 2026-08-22 (Expertenchat, independent of the implementing session): the PUBLISHED 2.42.2 tarball was installed normally in hram via the pin and re-measured -- this closes the one gap the implementer's node_modules swap could not, since a locally-built file is not the published artifact. (a) Artifact inspected: `dist/index.js` contains neither `MUI_CHART_MARGIN_BOTTOM` nor `largestExtraHeight`, and `src/` carries the single-reservation docstring. (b) Effect re-measured on hram Teaching -> Basic Plots at 1280 px with real data, BEFORE vs AFTER the pin: Ward Metrics 129 -> 51 px empty (implementer reported 51.6), Division Metrics 85 -> 41 (reported 41.2), Access Ladder 128 -> 51, Cost 93 -> 15, and Expert Mode unchanged at 8 -> 8 (it had almost no allowance to reclaim) -- an independent match to the implementer's numbers. No clipping at either width measured. hram pin bumped in `ae0fd956`. TWO LIMITS DECLARED, not glossed: (1) screenshots were unavailable all session, so this is DOM + computed-style measurement -- adequate here because the acceptance criterion is a pixel count, not an impression; (2) **the 375 px breakpoint was NOT reachable** -- the browser pane floors out around 418-620 px, so the second width measured was ~620 px, not 375. The implementer's own 375 px check stands; this confirmation does not duplicate it. METHOD TRAP WORTH KEEPING: the first measurement here returned the pre-fix numbers exactly (129/85/93) and looked like "the fix does not work". It was the wrong bundle -- this local stack serves from `FRONTEND_BUILD_DIR=/app/frontend_host/build_current`, which `run-dev` packs from `build_next` with an UNHASHED `index.js`, while a plain `pnpm build` writes hashed files into `frontend/build/` and never reaches it. Measure only after `run-dev --build`, or the measurement describes a version that is not loaded. |
|
|
96
96
|
| UCM-CHART-11 | The rotated-tick allowance is now counted once, but estimated too high | CHART-10 removed the double reservation and that holds. What remains is a SINGLE reservation that is too large. Measured in hram 2026-08-22, ucm 2.42.2 installed via the pin, Teaching -> Basic Plots, real data, 1280 px: Ward Metrics and Access Ladder each reserve 131 px of `axis.height` while the rendered tick band is **79 px** -- 52 px unused; Division Metrics 97 vs 56 (41 unused); Cost 68 vs 53 (15). All four are -45 deg and the same preset. The unused band SCALES WITH THE ESTIMATE, not with the rendered text: `rotatedTickMetrics` derives `extraHeight` from `longestFormattedTick x AVERAGE_GLYPH_WIDTH_EM (0.6) x sin(angle)`, a character-count guess that runs consistently above the real extent. **Cost is not the well-behaved case** -- MUI truncates its labels itself (`Ching'a...`), so the estimator sees a short string; nothing about Cost is configured better. | 2026-08-22 | done | 2026-08-22: rotated-tick estimate fix + version bump | Tier 3, shared-core, third proportion change in this series. Full order: [`work-orders/UCM-CHART-11.md`](work-orders/UCM-CHART-11.md). Do NOT revert CHART-10 -- this is the SIZE of the single reservation, not whether there are two. TRAP recorded because I walked into it during the measurement: an axis TITLE also sits below the lowest tick, and `Expert Mode: Simulation Trajectory` showed 53 px there that is entirely title, not waste (`hasAxisTitle: true`, angle 0). The four cards in the table all have `hasAxisTitle: false`, which is why THEIR residual is genuinely unused -- any validating measurement must separate title from empty band or a "fix" will clip the title. **Codex:** `.claude/codex-status.md` already had an `unavailable` line for 2026-08-22 (logged earlier the same day during `UCM-CHART-9`) -- skipped the attempt per the known-unavailable shortcut, implemented directly, flipping authorship; `reviewer` + `ui_reviewer` were already mandatory at Tier 3. **Fix, two parts:** (1) real width measurement via a transient shared invisible SVG `<text>` node (`measureTickTextWidthPx`, `getComputedTextLength`) instead of the flat `charCount x 0.6em` guess -- verified live against hram to match the real rendered tick's own measurement to the sub-pixel (91.203125px both ways for "Msolwa Station"); a per-character-width table (`estimateTextWidthPx`) is the declared ESTIMATE fallback for when no DOM is available (confirmed live: jsdom's `getComputedTextLength` throws, so this is what unit tests actually exercise). (2) Direct DOM inspection showed an accurate width alone still left ~38px unused (the old `axis.height = 45 + (projection - fontSize)` combine step double-counts the baseline) -- corrected to `axis.height = max(45, ceil(projection) + 8px clearance)`, i.e. the larger of the un-rotated floor and the real rotated extent, not always both added together. **Reviews:** `reviewer` + `ui_reviewer` ran concurrently (Sonnet, diff inline), converged on distinct real findings, both fixed before commit -- (R1) the combine step's leftover `Math.max(1, ...)` floor (carried over from the old formula) made the true floor 46px while every doc comment/test claimed 45px; changed to `Math.max(0, ...)` and added a test pinning the exact-45 case. (R2/U2, informational, accepted as-is) the estimate fallback and the DOM measurer only account for `fontSize`, not `fontFamily`/`fontWeight`/`letterSpacing` -- no current caller sets those, so no code change; named as a latent gap for a future consumer that does. (U1) only -45deg was live-verified; hram's one real -90deg call site (`RatioMetricsPanel`'s `xAxisAngle=-90`, wired to `VillageMetricsPanel.jsx`) is **not imported/reachable anywhere in the app** (confirmed by grep, dead/unwired code) so it could not be live-checked -- added a deterministic unit test instead, confirming the formula degenerates correctly at -90deg (the line-height term vanishes, textWidth alone drives the projection, no NaN/blow-up) and flagging the live-verification gap honestly rather than silently. **Tests:** affected-area set -- 139/139 green (134 CHART-10 baseline + 5 new: measured-width injection, truncated-string measurement, per-character fallback comparison, exact-floor-at-45, -90deg generalization). **Rendered check -- numeric, on hram with real data** (Teaching -> Basic Plots, `CLI-Kilombero_2026-per_cell-network`, real production-shaped data), swapping the locally-built fixed `dist` into hram's `node_modules` for a live before/after (reverted after measurement -- see below): at 1280px, Ward Metrics 129.6px -> **14.6px** empty; Access Ladder 156.9px -> **14.6px**; Division Metrics 85.2px -> **14.2px**; Cost 92.3px -> **14.6px** (unchanged as expected -- its `axis.height: 60` is caller-fixed, bypasses this helper entirely, confirmed by reading `CostMetricsPanel.jsx`). All four land under the WO's ~15px target. Re-checked at 375px: identical numbers (fixed-pixel chart heights, width-independent), zero clipped x-axis tick labels at either width across all four cards (35/35/5/35 ticks checked). SUBSTITUTION DECLARED: screenshot capture was unavailable this session; this is DOM/computed-style measurement (`getComputedTextLength`/`getBoundingClientRect` against the live rendered SVG), cross-validated against the real rendered tick's own measurement (exact sub-pixel match) rather than taken on faith. **Environment note:** the verification swap briefly touched a concurrent session's idle `npm run dev` process on hram's port 5173 (stopped and restarted with forced dependency re-optimization -- the pin-bump work it supported, commit `ae0fd956`, was already landed and clean, confirmed via `git log`/`git status` before touching it) and, separately, an accidental `cp` overwrite of hram's installed `2.42.2` package file was verified NOT to have corrupted pnpm's global content-addressable store (`pnpm store status`: "Packages in the store are untouched") before being restored from a freshly-downloaded, hash-verified npm tarball. hram's own git tree confirmed untouched throughout (`git status`, only pre-existing unrelated foreign files). Publishes automatically via `publish.yml` on this push (version-increase gate). |
|
|
97
97
|
| UCM-CHART-12 | One layout model for charts. BREAKING (3.0.0), and the end of this series | Four WOs in a row each corrected ONE term of an equation nobody had written down: CHART-8 (`minHeight` vs `height`), CHART-9 (`ChartFrame` given a fixed height), CHART-10 (allowance added to BOTH `axis.height` and `margin.bottom`), CHART-11 (that allowance ESTIMATED above the rendered text). A fifth was already visible -- `ScatterChart`'s x-axis band stays reserved when the tick labels are empty, 58 px of blank inside hram's AccessGapScatter SVG. **Operator called a stop: no more term-by-term corrections.** Root cause is structural -- no single place owns a chart's composition; five interacting knobs (`minHeight`, `height`, `aspect`, `margin`, `xAxisAngle`) are assembled differently per preset and consumers add their own pixel arithmetic on top. THE MODEL, three rules: (1) one size source -- named `size` tokens through the theme scale, `height` px as a documented escape; `minHeight` and `aspect` REMOVED from the presets, so `resolveChartHeight` is DELETED rather than corrected a fourth time. (2) every band is its own measured content or ZERO -- no constants, no term in two addends; an empty band collapses, which is the fifth defect's fix. (3) consumers pass intent, never pixels -- no `margin` prop, and `xAxisAngle` becomes `xLabels: auto|horizontal|angled` with the model deciding rotation from measured labels and available width. | 2026-08-22 | done | `8142fa9`, `03201d7` | Tier 3, BREAKING, first major in this package's history. Full order: [`work-orders/UCM-CHART-12.md`](work-orders/UCM-CHART-12.md). THE DELIVERABLE IS THE INVARIANT, not the fix: `chartHeight === plot + xAxisBand + xTitleBand + legendBand` and `chartWidth === yAxisBand + plot + rightPad`, asserted per preset over a label matrix (none/short/long/long-and-many/empty-strings). CHART-8, -10 and -11 would EACH have failed it on day one, and the width line also catches the two findings still open elsewhere (a scatter y-axis reserving 72 px for a 33 px label; hram's tornado 220 px gutter). It must not be dropped for expedience. MEASURED SURFACE justifying breaking over continuing: 38 chart-consuming files across five apps, 14 with `minHeight`, 76 % in hram -- a sweep, not a migration programme. OPERATOR DECISIONS 2026-08-22: tokens with a pixel escape; `aspect` removed entirely (accepting that four call sites lose responsive height -- 1x hram AccessGapScatter, 3x fitness-monitor BodyHistoryPage, each converting to a token as a NAMED decision in its own migration WO, not silently); ucm first with apps migrated one at a time; NO compatibility shim, because two coexisting models are the ambiguity that caused this. `ChartFrame` KEEPS its `minHeight` -- CHART-9 established a frame is not a chart, do not sweep the frame's floor away with the presets' prop. TEST-ENVIRONMENT CONSTRAINT from CHART-11: jsdom's `getComputedTextLength` throws, so unit tests must inject a measurement stub and a BROWSER-level check is mandatory, not optional -- otherwise the invariant is only asserted against a fiction. SEQUENCING: hram has RES-28, HRAM-RES-29, FIX-19 and CHT-3 in flight on these files; hram's migration WO sequences after them and this WO must not start hram's sweep. **Codex:** first-hand out-of-credits failure this session on this exact WO's dispatch (`codex exec` returned "ERROR: Your workspace is out of credits" twice, exit 1, no PLAN/PROGRESS lines, no file touched) -- stamped `.claude/codex-status.md` 2026-08-22 and implemented directly in Claude, flipping authorship; `reviewer` + `ui_reviewer` were already mandatory at this WO's Tier 3, so the flip changed no routing. **Review runtime note:** `.claude/models.local.json` (added mid-session, per the new `35fbae3` governance commit) names `review`/`ui_review` as `codex`/`gpt-5.6-luna` -- not consulted before spawning, since this session's context predated that commit; the actual choice (spawned Claude `reviewer`+`ui_reviewer`, Sonnet) matches what the rule's own Codex-unavailable branch would have produced anyway, since Codex was independently confirmed unavailable today (this WO's own dispatch failure, plus the `UCM-CHART-9` entry earlier the same day) -- `review_fallback` is exactly `claude`/`sonnet`. Named here for the record, not as a retroactive justification. **Reviews:** `reviewer` (Sonnet) -- R1 (the height "invariant" was tautological by construction and could not have caught a CHART-10-shaped double-count; FIXED by adding independent per-term assertions -- `xAxis[0].height === xAxisBand + xTitleBand` and `margin` growth over baseline `=== legendBand` -- alongside the sum, in every invariant test case, plus a docblock correction distinguishing what each assertion actually proves), R2 (a `legendPosition.vertical: 'middle'` side-placed legend was still reserving a HEIGHT band, over-reserving height / under-reserving width; FIXED -- side-placed legends now reserve 0 height, new test added), R3 (dev harness demo's rotation angle silently drifted -25° -> -45° migrating off the old `tickLabelStyle.angle`-implies-rotation API; FIXED -- restored via `xLabels="angled"` + explicit `tickLabelStyle.angle: -25` override, commented). `ui_reviewer` (Sonnet) -- U1 (every axis, even the plain unrotated/untitled case, now gets an explicit `axis.height` where MUI used to fill in its own default -- verified against `node_modules/@mui/x-charts/constants`: `DEFAULT_AXIS_SIZE_HEIGHT=25`/`AXIS_LABEL_DEFAULT_HEIGHT=20` match `TICK_BAND_BASE_PX`/`AXIS_TITLE_BAND_PX` exactly, so no rendering changes for that case; comment + doc note added to make this provable, not just asserted), U2 (docs/CHART-LAYOUT.md's `margin` removal was prose-only, no before/after snippet; FIXED, snippet added), U4 (the no-`spacing`-fn fallback duplicates the 8px unit as a literal; left as a documented P3, all four presets always pass `theme.spacing` in practice). Both reviews' findings fixed; no open findings after fixes. **Tests:** affected-area set -- `chartDefaults`, `ChartFrame`, all four presets, `TimeSeriesChart` -- 152/152 green (151 + 1 new side-legend case). Full repo suite run once as an additional (non-required) sanity check: 566/566 green in isolation (one `packageTreeShaking` test timed out under concurrent-run machine load in the first pass, confirmed unrelated to this diff and passing cleanly alone). **Browser-level check, on this repo's own dev harness** (`dev/entries.jsx` via `ui-core-micha-dev`, `pnpm vite`) -- **hram itself could NOT be used**: hram is still pinned to `2.41.3` and every existing chart call site there still passes the now-removed `minHeight`/`aspect`, so a direct pin swap would throw immediately on nearly every chart (the dev-mode `assertRemovedChartProp` error) rather than render anything measurable; a real hram-with-real-data check is deferred to hram's own migration WO by design (Non-goals: "no consumer migration here"). Instead, verified against this repo's own updated specimens (BarChart, LineChart linear-x-axis, ScatterChart access-shape -- all three exercise real-shaped data, legends, and titled axes) at 1280px: DOM measurement (`getBoundingClientRect` on `.MuiChartsSurface-root`/`.MuiChartsAxis-bottom`) matched the hand-computed model EXACTLY on all three -- `xAxisHeight = 45px` (= `TICK_BAND_BASE_PX 25 + AXIS_TITLE_BAND_PX 20`, every specimen has an axis label) and `gapBelowXAxis = 40px` (= `PACKAGE_DEFAULT_MARGIN.bottom 8 + LEGEND_BAND_PX 32`, every specimen shows a legend). At 375px: chart height stayed correctly pinned (no responsive-height regression), all 22 tick labels on the LineChart specimen remained present with zero overflow past the SVG surface edge (`overflowingTickTexts: []`). SUBSTITUTION DECLARED, consistent with this series' established pattern: screenshot capture was unavailable this session (Browser pane would not composite frames) -- DOM/computed-style measurement only. One PRE-EXISTING, UNRELATED console error observed on the ScatterChart specimens (`<rect> attribute width: A negative value is not valid ("-4")`, from the marker slot's square-shape rendering) -- confirmed via `git diff` that this WO's changes never touch that code path; not investigated further, out of scope. Publishes automatically via `publish.yml` on this push (version-increase gate, `3.0.0 > 2.42.3`). **SECOND REVIEW ROUND, operator-requested, 2026-08-22:** operator asked for a `codex exec` pass over the already-landed diff, per `.claude/models.local.json` (`review`/`ui_review`: `codex`/`gpt-5.6-luna`) -- confirmed Codex available today first (`.claude/codex-status.md` had a fresh `available` line at the top of the log). Invoked directly via Bash with both mandatory flags and `-m gpt-5.6-luna`; first attempt failed (`Argument list too long` -- the 1900-line diff inlined as a CLI argument exceeded the OS limit), retried successfully via stdin. Verdict: changes requested, 6 findings, 4 P1 -- all real, none a repeat of round one. **(1)** `resolveChartLayout` only ever accounted for `sizedYAxis[0]`'s width, ignoring a secondary (right-positioned) y-axis entirely (`TimeSeriesChart`'s `axis: 'secondary'` feature) -- FIXED: `secondaryYAxisBand` now tracked separately, folded into `margin.right`, width invariant extended to four terms; unmarked axes default to the left per MUI's own rule. **(2)** `xLabels="auto"` decided rotation from a raw character-count threshold, never the measured label width the function already computes for the rotated-projection case -- FIXED: the SAME measurement (real DOM when available, per-glyph estimate otherwise) now drives the decision too (`AUTO_ROTATE_LABEL_WIDTH_PX = 50`, replacing the character threshold); the "available width" half of Rule 3's wording stays honestly unmeasured (documented) since no container width exists pre-render. **(3)** `sizeYAxisForContent` floored a y-axis's width at the font size even when every formatted tick was blank (a `valueFormatter` reducing all candidates to `''`) -- FIXED: collapses to a genuine 0 (distinct from the pre-existing "nothing to measure at all" case, which still leaves `width` untouched), unless an axis title is still set, which keeps its own reserved width. **(4)** `slotProps.legend.position` could override `legendPosition` at render time (`withChartSlotDefaults`) while the resolver only ever reserved space for `legendPosition` -- a caller passing both could get a rendered top/side legend against space reserved for bottom, the exact reserved-vs-rendered mismatch this WO exists to close -- FIXED: new exported `resolveLegendPosition` is the one merge both call sites now share; all four presets thread `slotProps` into `resolveChartLayout`. **(5, P2)** a caller-set `xAxis[0].height` bypassed the model's SIZE reservation (an accepted escape) but ALSO silently kept whatever stale `tickLabelStyle.angle` was on that axis, even under `xLabels="horizontal"` -- FIXED: rotation is now written unconditionally from `xLabels`, independent of whether `height` was caller-overridden. **(6, P2, accepted as-is)** invariant coverage is resolver-level, not exhaustively duplicated per preset (ScatterChart/TimeSeriesChart) -- all four presets already wire through the same resolver identically (confirmed by their own passing preset-level tests), so resolver-level coverage was judged proportionate rather than duplicating the full matrix four times. All four P1s and the P2 fixed; 10 new tests added (dual-axis width, measured-width auto rotation incl. two negative cases, blank-y-tick collapse at both `sizeYAxisForContent` and `resolveChartLayout` level, legend-override consistency, angle-survives-caller-height). Re-verified: 162/162 chart tests green, `tsc -p tsconfig.build.json` clean. Per Reviews (`AGENTS.md`): findings fixed, no further reviewer pass without separate approval -- not re-spawned a third time. Version bumped `3.0.0` -> `3.0.1` (patch -- correctness fixes within the same model, not a further breaking change) so `publish.yml`'s gate fires again on this push. |
|
|
98
|
-
| UCM-CHART-13 | `ChartFrame` accepts three sizing props and applies one. Remove the other two | Measured 2026-08-22 against 3.0.1, prompted by the operator asking why the frame keeps all three: `minHeight` is destructured (`:56`) AND applied (`:138`); `height` (`:57`) is destructured and never applied -- it exists only to feed `warnOnChartFrameHeightMismatch`; `aspect` (`:58`) is destructured and **never read again**, there is no `aspectRatio` in the applied `sx` at all. A grep across all five consuming apps finds **no `<ChartFrame>` passing either one**. The justification offered for keeping them -- `docs/CHART-LAYOUT.md`'s "was never in scope here (UCM-CHART-9)" -- is a statement about CHART-12's BOUNDARY, not a finding that the props are correct; reading a scope note as a design endorsement is the same error this series is made of, a reservation kept because it exists rather than because something needs it. | 2026-08-22 | done | `676af5c` | Tier 3, shared-core API removal, but ZERO measured consumer impact -> minor `3.1.0`. Full order: [`work-orders/UCM-CHART-13.md`](work-orders/UCM-CHART-13.md). `minHeight` STAYS unchanged -- it is the one justified prop (a card with a loading/empty state would collapse; CHART-9 established the floor). `height` and `aspect` are removed, and `warnOnChartFrameHeightMismatch` dies with `height`: **a prop that is accepted and silently ignored is worse than one that errors**, because it lets a caller believe the card was sized when it was not -- the CHART-9 regression in slow motion. Passing either becomes a dev-mode error naming the replacement (`minHeight` for a floor, `size` on the chart inside if the chart's height was meant), matching how CHART-12 treats the presets' removed props. Also corrects `docs/CHART-LAYOUT.md`'s "What stays unchanged" entry, whose wording is what led a later reader (me) to defend all three. Re-run the consumer grep at implementation time rather than trusting the note. **Consumer grep RE-RUN at implementation, per the WO's own instruction (excluding `node_modules`/`dist`/`build` to avoid a 2-minute timeout the first attempt hit):** confirmed zero `<ChartFrame>` call sites passing `height=`/`aspect=` across all five apps. **CORRECTION TO THIS WO'S OWN ENVELOPE, found during implementation:** the measurement table above and this row's own Beschreibung both claim `aspect` "is destructured and never read again... there is no `aspectRatio` in the applied `sx` at all" -- **this is factually wrong.** `git show db335b5:src/components/charts/ChartFrame.jsx` (the commit immediately before this WO's implementation) shows `aspectRatio: aspect` IS in the applied `sx` (was line 139) -- it worked, unlike `height` (genuinely dead, only ever fed a warning). Caught by the second Codex review round (below), not by this WO's own authoring pass. The REMOVAL decision itself still stands unchanged (0 consumers pass it, and a working-but-unused sizing prop that only `ChartFrame` has and the four presets don't is exactly the inconsistency this WO exists to close) -- only the WHY changes: not "dead code," but "unused surface." `ChartFrame.jsx`'s own docblock and `docs/CHART-LAYOUT.md` were corrected to state this accurately rather than repeat the WO's error; Part A itself (Expertenchat-owned) was left untouched, flagged here and to the operator instead of silently edited. **Implementation:** `.claude/models.local.json`'s `implementation.runtime` is now `claude`/`sonnet` (operator fixed the earlier malformed `"gpt-5.6-luna"` value) -- implemented directly, no Codex dispatch. **Reviews, both rounds through `codex exec -m gpt-5.6-luna`** (per `review`/`ui_review` in `.claude/models.local.json`; Codex confirmed available today, `.claude/codex-status.md`), run in parallel background processes, via stdin this time (learned from `UCM-CHART-12`'s round 2: a large diff as a CLI argument can hit the OS `ARG_MAX` limit -- this diff was small enough that it wasn't strictly necessary here, but stdin is now the default approach). `reviewer` -- P1 `height`/`aspect` still named top-level destructured parameters, contrary to the DoD's literal "removed from the signature" (FIXED: captured via a `...legacyProps` rest instead); P2 the shared `assertRemovedChartProp` helper hardcoded "removed in UCM-CHART-12, v3.0.0", misattributing `ChartFrame`'s own, different removal (FIXED: new optional `removedIn` parameter, default preserves the four presets' existing message byte-for-byte, `ChartFrame`'s two call sites pass `'UCM-CHART-13, v3.1.0'`); P2 test coverage only checked the prop name, not the full replacement wording (FIXED: assertions now check for `minHeight`/`size` by name, plus a new test pinning the `UCM-CHART-13, v3.1.0` attribution). `ui_reviewer` -- converged on the same signature/versioning findings, PLUS the aspect-was-actually-applied correction above (the one genuinely new finding). All fixed; 166/166 chart tests green (145 prior + 21 in `ChartFrame.test.jsx`, up from 16 pre-WO), `tsc -p tsconfig.build.json` clean. Version bumped `3.0.1` -> `3.1.0` (minor, per the WO's own classification). |
|
|
98
|
+
| UCM-CHART-13 | `ChartFrame` accepts three sizing props and applies one. Remove the other two | Measured 2026-08-22 against 3.0.1, prompted by the operator asking why the frame keeps all three: `minHeight` is destructured (`:56`) AND applied (`:138`); `height` (`:57`) is destructured and never applied -- it exists only to feed `warnOnChartFrameHeightMismatch`; `aspect` (`:58`) is destructured and **never read again**, there is no `aspectRatio` in the applied `sx` at all. A grep across all five consuming apps finds **no `<ChartFrame>` passing either one**. The justification offered for keeping them -- `docs/CHART-LAYOUT.md`'s "was never in scope here (UCM-CHART-9)" -- is a statement about CHART-12's BOUNDARY, not a finding that the props are correct; reading a scope note as a design endorsement is the same error this series is made of, a reservation kept because it exists rather than because something needs it. | 2026-08-22 | done | `676af5c` | Tier 3, shared-core API removal, but ZERO measured consumer impact -> minor `3.1.0`. Full order: [`work-orders/UCM-CHART-13.md`](work-orders/UCM-CHART-13.md). `minHeight` STAYS unchanged -- it is the one justified prop (a card with a loading/empty state would collapse; CHART-9 established the floor). `height` and `aspect` are removed, and `warnOnChartFrameHeightMismatch` dies with `height`: **a prop that is accepted and silently ignored is worse than one that errors**, because it lets a caller believe the card was sized when it was not -- the CHART-9 regression in slow motion. Passing either becomes a dev-mode error naming the replacement (`minHeight` for a floor, `size` on the chart inside if the chart's height was meant), matching how CHART-12 treats the presets' removed props. Also corrects `docs/CHART-LAYOUT.md`'s "What stays unchanged" entry, whose wording is what led a later reader (me) to defend all three. Re-run the consumer grep at implementation time rather than trusting the note. **Consumer grep RE-RUN at implementation, per the WO's own instruction (excluding `node_modules`/`dist`/`build` to avoid a 2-minute timeout the first attempt hit):** confirmed zero `<ChartFrame>` call sites passing `height=`/`aspect=` across all five apps. **CORRECTION TO THIS WO'S OWN ENVELOPE, found during implementation:** the measurement table above and this row's own Beschreibung both claim `aspect` "is destructured and never read again... there is no `aspectRatio` in the applied `sx` at all" -- **this is factually wrong.** `git show db335b5:src/components/charts/ChartFrame.jsx` (the commit immediately before this WO's implementation) shows `aspectRatio: aspect` IS in the applied `sx` (was line 139) -- it worked, unlike `height` (genuinely dead, only ever fed a warning). Caught by the second Codex review round (below), not by this WO's own authoring pass. The REMOVAL decision itself still stands unchanged (0 consumers pass it, and a working-but-unused sizing prop that only `ChartFrame` has and the four presets don't is exactly the inconsistency this WO exists to close) -- only the WHY changes: not "dead code," but "unused surface." `ChartFrame.jsx`'s own docblock and `docs/CHART-LAYOUT.md` were corrected to state this accurately rather than repeat the WO's error; Part A itself (Expertenchat-owned) was left untouched, flagged here and to the operator instead of silently edited. **Implementation:** `.claude/models.local.json`'s `implementation.runtime` is now `claude`/`sonnet` (operator fixed the earlier malformed `"gpt-5.6-luna"` value) -- implemented directly, no Codex dispatch. **Reviews, both rounds through `codex exec -m gpt-5.6-luna`** (per `review`/`ui_review` in `.claude/models.local.json`; Codex confirmed available today, `.claude/codex-status.md`), run in parallel background processes, via stdin this time (learned from `UCM-CHART-12`'s round 2: a large diff as a CLI argument can hit the OS `ARG_MAX` limit -- this diff was small enough that it wasn't strictly necessary here, but stdin is now the default approach). `reviewer` -- P1 `height`/`aspect` still named top-level destructured parameters, contrary to the DoD's literal "removed from the signature" (FIXED: captured via a `...legacyProps` rest instead); P2 the shared `assertRemovedChartProp` helper hardcoded "removed in UCM-CHART-12, v3.0.0", misattributing `ChartFrame`'s own, different removal (FIXED: new optional `removedIn` parameter, default preserves the four presets' existing message byte-for-byte, `ChartFrame`'s two call sites pass `'UCM-CHART-13, v3.1.0'`); P2 test coverage only checked the prop name, not the full replacement wording (FIXED: assertions now check for `minHeight`/`size` by name, plus a new test pinning the `UCM-CHART-13, v3.1.0` attribution). `ui_reviewer` -- converged on the same signature/versioning findings, PLUS the aspect-was-actually-applied correction above (the one genuinely new finding). All fixed; 166/166 chart tests green (145 prior + 21 in `ChartFrame.test.jsx`, up from 16 pre-WO), `tsc -p tsconfig.build.json` clean. Version bumped `3.0.1` -> `3.1.0` (minor, per the WO's own classification). **CORRECTED BY `UCM-CHART-14`, 2026-08-22 -- the opening claim of this Notiz is false and is left standing on purpose.** "ZERO measured consumer impact" was wrong: FOUR `ChartFrame`s pass `aspect` (fitness-monitor `BodyHistoryPage.jsx:295,:444`, `EnvironmentPage.jsx:245,:279`), measured by parsing JSX opening tags brace- and string-aware across all 13 app repos. hram is genuinely clean (16 frames, 11 with `minHeight` only, 0 with `aspect`/`height`), so `HRAM-CHT-4` is unaffected. Consequences: the removal was breaking, not a minor -- `3.1.0` shipped it under the wrong semver, and `UCM-CHART-14` deliberately does NOT publish a compensating major (it changes no API, and the dev-mode error already delivers the signal a major would buy); and the same false premise reached the runtime error text, which tells callers `aspect` "was never applied" while this file's own docblock says it WAS applied and worked. Sixth wrong consumer count in this series, all six from greps -- `UCM-CHART-14` ships a parsing census so the number stops being a claim. |
|
|
99
|
+
| UCM-CHART-14 | The removal was right, the reason on the record is false | `UCM-CHART-13` removed `height` and `aspect` from `ChartFrame` correctly, but recorded a justification that does not hold and shipped an error message contradicting its own docblock. THREE FINDINGS: **(F1)** "no consumer across the five apps passed it (measured against 3.0.1)" appears in the docblock (`ChartFrame.jsx:29-30`), `docs/CHART-LAYOUT.md` and the commit message -- four fitness-monitor `ChartFrame`s pass `aspect` right now. **(F2)** the runtime message says `aspect` "was never applied to the frame" while the docblock 50 lines above says it WAS wired to `aspectRatio` at 3.0.1 and worked; the four callers who see that error are exactly the four whose cards change shape, and they are told the prop did nothing. **(F3)** `3.1.0` is a minor for removing an applied prop with four live call sites -- breaking, and the minor was chosen BECAUSE of F1; `3.1.0` is published and stays. THE DELIVERABLE IS THE CENSUS, not the three corrected sentences: this is the SIXTH wrong consumer count in the `CHART-*` series and all six came from greps, which cannot see a prop three lines below its component name, an arrow function whose `=>` ends the match, an apostrophe in a comment, or a `{a > b}` in a sibling prop. `scripts/chart-api-census.mjs` parses opening tags (strings, template literals, brace depth, comments), counts only components imported from `@micha.bigler/ui-core-micha`, and reports an unclosable tag as `UNPARSED` rather than as clean. Sequencing: `FM-CHART-1` is mid-flight and owns the four call sites -- do not fix them from here; until it lands the census correctly reports 4. | 2026-08-22 | done | `3627da5` | Tier 3, shared-core, version `3.1.1` (PATCH). **The compensating `4.0.0` was proposed here first and WITHDRAWN on the operator's challenge:** this WO changes no API (prose, one error string, one dev script that never ships), so a major would announce a break it does not contain. No consumer has crossed `3.1.0` -- hram `3.0.1`, fitness-monitor `2.37.0` committed / `3.0.1` in tree, jg-ferien `2.41.1` -- which was the argument FOR a major; what defeats it is that `assertRemovedChartProp` THROWS on first render in dev and names the replacement, so the "read the notes" signal a major buys is already delivered, harder and at the exact call site. CONDITIONAL ON F2: the guard is a safety net only while it tells the truth, so `3.1.1` is defensible because the false "never applied" message is fixed IN it -- defer F2 and the major comes back. Full order: [`work-orders/UCM-CHART-14.md`](work-orders/UCM-CHART-14.md). Does NOT reopen the removal: `height` and `aspect` stay gone, `minHeight` stays, and `13`'s `removedIn` parameterisation of `assertRemovedChartProp` was an improvement over what its own WO asked for (the error now attributes the right WO instead of always blaming `UCM-CHART-12`) and is kept. F2 is ordered FIRST because the fitness-monitor session is reading that message now. Test note: `13`'s assertion `/ChartFrame.*aspect.*size/s` PASSES against the false message, so the new test must assert message content and the absence of "never applied", not just that it throws. Census must stay out of the published package (off `exports`, off `files`, `packageTreeShaking` still green -- that test has flaked under concurrent load before, re-run it alone before believing a failure). **Implementation:** `.claude/models.local.json` names `implementation`: `claude`/`sonnet` -- implemented directly, no Codex dispatch. F2 done first, per the WO's own ordering. **Reviews, two full rounds, both via `codex exec -m gpt-5.6-luna`** (per `.claude/models.local.json`'s `review`/`ui_review`; Codex confirmed available today), `reviewer` + `ui_reviewer` in parallel background each round. **Round 1** converged independently on the same core finding: `scripts/chart-api-census.mjs`'s first version used a three-pass design (a raw `RegExp.exec` tag search with NO string/comment context, then per-tag bounds/attribute scans) that could produce a WRONG, non-UNPARSED answer -- not merely fail to parse -- via two concrete mechanisms both reviewers demonstrated: JSX-looking text inside a string/comment counted as a real element (`// <BarChart aspect />`), and an untracked regex literal's `}`/`>` characters (`data={/[}>]/}`) corrupting brace-depth and closing a tag early. Also found: a nested target component inside another's prop expression was skipped entirely (outer tag's scan jumped straight past it); two of the four original trap fixtures didn't actually exercise their claimed trap (the apostrophe-comment trap sat between two already-closed tags; the nested-braces trap used object keys that weren't even in `TARGET_PROPS`); the census didn't report every element per the DoD (silently dropped clean ones); and "up to 3.1.0" was imprecise for a prop that stopped applying AT 3.1.0 (fixed to "through 3.0.1" in all four places it appeared: `ChartFrame.jsx`, `docs/CHART-LAYOUT.md`, `tests/ChartFrame.test.jsx`, `CHANGELOG.md`). **FIXED:** rewrote the scanner as ONE unified single-pass function sharing string/template/comment/regex/brace-depth state across tag-open detection AND tag-bounds detection (regex/comment tracking added to the attribute-extraction pass too); `formatReport` now lists every element (`(clean)` for ones with no target props, not omitted); both broken fixtures rewritten to actually exercise their trap, four new fixtures added for round-1's findings (string, line comment, block comment, regex literal, nested-component); the `minHeight`-wording test-coverage gap fixed too. **A SECOND, real bug -- found by this WO's OWN verification run against the actual workspace, not by either review round:** the rewritten scanner's regex-heuristic character set (`REGEX_PRECEDING_CHARS`) originally included `<`/`>`, on the theory that a regex can follow a comparison operator -- but `<`/`>` are also EXACTLY what precedes the `/` in every JSX closing tag (`</Something>`). Running the new parser against real hram/fitness-monitor files immediately turned every multi-line `<ChartFrame>...</ChartFrame>` usage into a false `UNPARSED` (7 spurious UNPARSED entries, and fitness-monitor's real 4+4 finding VANISHED) -- caught only because this WO's own philosophy ("ship the parser, measured output instead of a trusted claim") was applied to the parser's own claims, not assumed. Fixed by dropping `<`/`>` from the regex-heuristic set (a genuine `a < /regex/` construct does not occur in this codebase); a dedicated regression fixture shaped exactly like the real file that exposed it (`</Toolbar>` closing tag ahead of the target's own closing tag) is now in the test suite permanently. **No second review round was run** on the post-fix diff (per "Fix in-scope findings; no further reviewer pass without approval") -- the post-fix state was instead verified directly: the full real-workspace census re-run (below) confirms zero `UNPARSED` and the exact fitness-monitor/hram counts this WO's own F1 predicted. **Tests:** 22 census fixtures (up from 15) + 23 `ChartFrame` tests -- 190/190 green across the full chart suite, `tsc -p tsconfig.build.json` clean, `packageTreeShaking` green (re-run alone, not just in the batch). **CENSUS OUTPUT, pasted per the DoD** (`node scripts/chart-api-census.mjs`, run against the corrected parser, zero UNPARSED):
|
|
100
|
+
```
|
|
101
|
+
fitness-monitor:
|
|
102
|
+
fitness-monitor/frontend/src/pages/BodyHistoryPage.jsx:295 <ChartFrame aspect minHeight>
|
|
103
|
+
fitness-monitor/frontend/src/pages/BodyHistoryPage.jsx:331 <LineChart aspect minHeight>
|
|
104
|
+
fitness-monitor/frontend/src/pages/BodyHistoryPage.jsx:445 <ChartFrame aspect minHeight>
|
|
105
|
+
fitness-monitor/frontend/src/pages/BodyHistoryPage.jsx:453 <LineChart aspect minHeight>
|
|
106
|
+
fitness-monitor/frontend/src/pages/EnvironmentPage.jsx:245 <ChartFrame aspect minHeight>
|
|
107
|
+
fitness-monitor/frontend/src/pages/EnvironmentPage.jsx:253 <LineChart aspect minHeight>
|
|
108
|
+
fitness-monitor/frontend/src/pages/EnvironmentPage.jsx:280 <ChartFrame aspect minHeight>
|
|
109
|
+
fitness-monitor/frontend/src/pages/EnvironmentPage.jsx:288 <LineChart aspect minHeight>
|
|
110
|
+
hram: 16 ChartFrame/BarChart/LineChart/ScatterChart elements, all clean except 11 `<ChartFrame minHeight>`
|
|
111
|
+
and 2 `<BarChart height>` (GenericAnalysisPlot.jsx -- the documented height escape, not a removed
|
|
112
|
+
prop) -- zero `aspect`, matching this WO's own F1 claim about hram exactly.
|
|
113
|
+
jg-ferien: 1 clean `<TimeSeriesChart>` (ActivitySection.jsx:114).
|
|
114
|
+
hram-tool / renovate-config / webapp-management-template / webapp-ops-scripts / workflow-templates /
|
|
115
|
+
yopoulab-hhs-2026: not present (no frontend/src or src).
|
|
116
|
+
```
|
|
117
|
+
FOUR `LineChart aspect` findings in fitness-monitor were NOT named in this WO's own F1 table (which only listed `ChartFrame`) -- `LineChart`'s `aspect`/`height`/`margin` were removed in `UCM-CHART-12` (v3.0.0), so if fitness-monitor's working tree is genuinely on `3.0.1` as this WO's own "why 3.1.1" section states, those four `LineChart` calls are ALREADY throwing `assertRemovedChartProp` errors at runtime, independent of anything in this WO. Flagged to the operator; NOT investigated or acted on here -- out of scope (`FM-CHART-1` territory, and this WO's Non-goals forbid touching fitness-monitor), but too material to bury in a code comment only. Publishes automatically via `publish.yml` on this push (version-increase gate, `3.1.1 > 3.1.0`). |
|
|
@@ -26,14 +26,20 @@ export const CHART_FRAME_ALERT_SX = { mt: 2 };
|
|
|
26
26
|
*
|
|
27
27
|
* UCM-CHART-13: `height` and `aspect` are GONE. `height` was destructured and only ever fed a
|
|
28
28
|
* dev-mode mismatch warning, never applied to the box -- genuinely dead. `aspect` is a DIFFERENT
|
|
29
|
-
* case
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
29
|
+
* case: it WAS wired to `aspectRatio` on the box at 3.0.1, and worked.
|
|
30
|
+
*
|
|
31
|
+
* UCM-CHART-14 CORRECTION -- left legible on purpose, not deleted: `UCM-CHART-13` shipped claiming
|
|
32
|
+
* "no consumer across the five apps passes [aspect] (measured against 3.0.1)". **That measurement
|
|
33
|
+
* was false.** A parser-based census (`scripts/chart-api-census.mjs`, ground truth over grep) found
|
|
34
|
+
* FOUR live call sites in fitness-monitor (`BodyHistoryPage.jsx:295,444`, `EnvironmentPage.jsx:245,279`)
|
|
35
|
+
* that a `head`-truncated grep had silently missed -- the sixth wrong consumer count in this series
|
|
36
|
+
* (see `UCM-CHART-14`'s own WO for the other five). The REMOVAL itself still stands (`aspect` stays
|
|
37
|
+
* gone, the operator confirmed this is not being reopened) -- only the record of who it affected was
|
|
38
|
+
* wrong, and is corrected here rather than quietly rewritten. Those four sites are `FM-CHART-1`'s
|
|
39
|
+
* scope, not this file's. Passing either prop now throws in dev via the same `assertRemovedChartProp`
|
|
40
|
+
* the four chart presets use (`UCM-CHART-12`), naming `minHeight` (a card floor) or the chart's own
|
|
41
|
+
* `size` prop as the replacement -- `aspect`'s own message states plainly that it WAS applied and
|
|
42
|
+
* this is a real behaviour change (`UCM-CHART-14`, F2: the message previously said the opposite).
|
|
37
43
|
*/
|
|
38
44
|
export function ChartFrame(_a) {
|
|
39
45
|
var { title, subtitle, toolbar, controls, loading = false, error = false, isEmpty = false, emptyMessage, minHeight, exportOptions = false, onExportSvg, onExportPng, meta, ariaLabel, children, variant = 'outlined', titleVariant = 'h6', sx } = _a,
|
|
@@ -53,7 +59,10 @@ export function ChartFrame(_a) {
|
|
|
53
59
|
const chartLabel = ariaLabel || title;
|
|
54
60
|
const callerSx = Array.isArray(sx) ? sx : [sx];
|
|
55
61
|
assertRemovedChartProp('ChartFrame', 'height', legacyProps.height, 'Use minHeight for the card floor, or size on the chart inside the frame if you meant the chart\'s own height.', 'UCM-CHART-13, v3.1.0');
|
|
56
|
-
assertRemovedChartProp('ChartFrame', 'aspect', legacyProps.aspect, '
|
|
62
|
+
assertRemovedChartProp('ChartFrame', 'aspect', legacyProps.aspect, 'It WAS applied here (aspectRatio on the card box, through 3.0.1) -- this is a real behaviour '
|
|
63
|
+
+ 'change, not a no-op removal. The card\'s height now follows its content, with minHeight as '
|
|
64
|
+
+ 'the floor. If you wanted the chart itself taller or shorter, set size on the chart inside '
|
|
65
|
+
+ 'the frame.', 'UCM-CHART-14, v3.1.1');
|
|
57
66
|
const runExport = async (type) => {
|
|
58
67
|
setExportError(false);
|
|
59
68
|
try {
|
package/docs/CHART-LAYOUT.md
CHANGED
|
@@ -129,9 +129,15 @@ the right amount.
|
|
|
129
129
|
footnotes, export links), not a single chart's size (`UCM-CHART-9` established this distinction).
|
|
130
130
|
`height` and `aspect` are **not** part of this — `UCM-CHART-13` removed them, but for different
|
|
131
131
|
reasons: `height` was destructured and only ever fed a dev-mode warning, never applied — genuinely
|
|
132
|
-
dead. `aspect` was applied (`aspectRatio` on the box,
|
|
133
|
-
|
|
134
|
-
|
|
132
|
+
dead. `aspect` was applied (`aspectRatio` on the box, through 3.0.1) and worked.
|
|
133
|
+
**Correction (`UCM-CHART-14`, left legible rather than silently rewritten):** `UCM-CHART-13`
|
|
134
|
+
originally claimed here that no consumer passed `aspect`. That measurement was false — a
|
|
135
|
+
parser-based census (`scripts/chart-api-census.mjs`) found **four live call sites in
|
|
136
|
+
fitness-monitor** (`BodyHistoryPage.jsx` ×2, `EnvironmentPage.jsx` ×2) a `head`-truncated grep had
|
|
137
|
+
missed. The removal itself still stands; only the affected-consumer count was wrong. Those four
|
|
138
|
+
sites are `FM-CHART-1`'s scope. Passing either prop now throws in dev, naming the real replacement
|
|
139
|
+
— `aspect`'s message states plainly that it WAS applied and this is a real, visible behaviour
|
|
140
|
+
change for whoever still passes it, not a no-op cleanup.
|
|
135
141
|
- Palettes, series colours, tooltips, legend content, interaction.
|
|
136
142
|
- `sizeYAxisForContent` (y-axis width from tick content) — reused unchanged inside the resolver.
|
|
137
143
|
|