@bicharts/chart-host 0.5.69 → 0.5.71

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/dist/index.mjs CHANGED
@@ -640,8 +640,8 @@ function launchGenerates(outcome) {
640
640
  function launchFavorStyle(outcome, autoSentinel) {
641
641
  return outcome.kind === "pick" ? outcome.chartType : autoSentinel;
642
642
  }
643
- var CHOOSER_MIN_WIDTH_PX = 400;
644
- var CHOOSER_MIN_HEIGHT_PX = 240;
643
+ var CHOOSER_MIN_WIDTH_PX = 320;
644
+ var CHOOSER_MIN_HEIGHT_PX = 220;
645
645
  function chooserFitsViewport(width, height) {
646
646
  if (!isFinite(width) || !isFinite(height)) return false;
647
647
  return width >= CHOOSER_MIN_WIDTH_PX && height >= CHOOSER_MIN_HEIGHT_PX;
@@ -105,14 +105,11 @@ export declare const FILTER_ROW_PX = 32;
105
105
  * THE SMALLEST CARD THE FILTER BOX IS USABLE IN - measured 2026-09-03, and NOT arithmetic off
106
106
  * `CHOOSER_MIN_*`.
107
107
  *
108
- * The chooser's own floor (400 x 240) was measured with three pinned elements. The filter row is
109
- * a FOURTH, in a card that clips, so the old envelope does not survive the addition and could not
110
- * be adjusted by adding 32px to it - the coupling between the two dimensions moves too.
108
+ * The chooser's floor was measured with three pinned elements. The filter row is a FOURTH, in a
109
+ * card that clips, so that envelope does not survive the addition and could not be adjusted by
110
+ * adding 32px to it - the coupling between the two dimensions moves too.
111
111
  *
112
- * Same harness as the 2026-09-01 chooser sweep, re-run over 195 sizes with the row present. The
113
- * run reproduces the chooser's published coupling exactly when the row is hidden (320-340 wide
114
- * needs 280 tall, 360-380 needs 260, 400+ needs 220), which is what says the harness is measuring
115
- * the same card and not a different one.
112
+ * Same harness as the 2026-09-01 chooser sweep, re-run over 195 sizes with the row present.
116
113
  *
117
114
  * ONE CRITERION IS TIGHTER, and it is the reason this is a separate floor rather than a bigger
118
115
  * version of the old one: the chooser sweep asked for TWO visible list rows, this asks for
@@ -126,6 +123,28 @@ export declare const FILTER_ROW_PX = 32;
126
123
  * height for the reason `CHOOSER_MIN_*` states: the measurement used one font stack and one
127
124
  * string, every host localizes the title, and a longer translation wraps sooner than the sample.
128
125
  *
126
+ * ⚠ THIS FLOOR INHERITED THE CHOOSER SWEEP'S DEFECT, AND HAS NOT BEEN RE-MEASURED (2026-09-04).
127
+ * This comment used to argue that reproducing the chooser's published coupling when the row is
128
+ * hidden (320-340 wide needs 280 tall, 360-380 needs 260, 400+ needs 220) proved the harness was
129
+ * measuring the same card. It proved the two sweeps SHARED A CARD, which is a different claim,
130
+ * and the re-measure behind `CHOOSER_MIN_*` shows the card they shared was not the one the
131
+ * product draws: rows were sized without the DESCRIPTION each one carries, so a row measured
132
+ * ~22px against a real 48. Every "N visible rows" number on both sweeps is therefore about twice
133
+ * as generous as the screen, and this floor's criterion is the tighter one, so it is the more
134
+ * affected of the two.
135
+ *
136
+ * IT IS LEFT ALONE ON PURPOSE, because the fix is not a re-run. Re-measuring "three visible rows"
137
+ * against 48px rows pushes this floor past any tile a report actually uses, which would retire a
138
+ * just-shipped control rather than place it. THE OPEN QUESTION IS THE CRITERION, NOT THE NUMBER:
139
+ * "three visible rows" was a proxy for "the reader can still skim the list", and on a card whose
140
+ * rows are twice as tall it no longer describes that. A plausible replacement is its inverse -
141
+ * offer the filter precisely once the list has STOPPED being skimmable, which is nearer to what
142
+ * a reader reaches for a filter box for. Settle that before re-deriving this constant.
143
+ *
144
+ * NOTE THE FRAME, when comparing the two numbers: this floor is measured on the CARD, and
145
+ * `CHOOSER_MIN_*` on the CONTAINER. The card is 95% of the container less 32px of padding, so
146
+ * 420 here is about a 476px tile - the two floors are further apart than the bare numbers read.
147
+ *
129
148
  * ERRING HIGH IS THE CHEAP DIRECTION, exactly as it is for the chooser. Below this floor the
130
149
  * reader gets the chooser they have today, unchanged; above it wrongly, they get a clipped
131
150
  * control in a card that cannot scroll to reveal it.
@@ -41,25 +41,57 @@ export declare function launchGenerates(outcome: QualifyLaunchOutcome): boolean;
41
41
  */
42
42
  export declare function launchFavorStyle<T>(outcome: QualifyLaunchOutcome, autoSentinel: T): string | T;
43
43
  /**
44
- * THE SMALLEST TILE THE CHOOSER IS USABLE IN, measured rather than guessed (2026-09-01).
45
- *
46
- * A sweep of 168 tile sizes in headless Chromium, rendering the real card DOM and CSS, asking
47
- * three questions of each: do the three launch buttons sit on one line inside the card, are at
48
- * least two list rows visible, and is nothing in the pinned chrome clipped. The measured floor
49
- * is 320 x 220 - but the two dimensions are COUPLED, because under 400 px the card's title
50
- * wraps to a second line and eats the list's height: at 320-340 wide the height floor rises to
51
- * 280, at 360-380 to 260, and only at 400+ does 220 hold.
52
- *
53
- * 400 x 240 is that envelope with one sweep step of margin on the height. The margin is not
54
- * decoration: the measurement used one font stack and one string, and every host localizes the
55
- * title, so a longer translation wraps sooner than the sample did.
56
- *
57
- * ERRING HIGH IS THE CHEAP DIRECTION. Below the floor the host generates immediately, which is
58
- * the behaviour it had before the chooser existed - so a tile wrongly judged too small costs a
59
- * feature, while one wrongly judged big enough costs a dialog whose buttons are off the card.
44
+ * THE SMALLEST TILE THE CHOOSER IS USABLE IN, measured rather than guessed - and RE-MEASURED on
45
+ * 2026-09-04, because the first measurement was taken on a card the product does not draw.
46
+ *
47
+ * WHAT THE FIRST SWEEP GOT WRONG (it shipped 400 x 240). It asked three questions of 168 tile
48
+ * sizes - do the three launch buttons sit on one line inside the card, are at least two list
49
+ * rows visible, is nothing in the pinned chrome clipped - and found that two rows fit at
50
+ * 400 x 220. Two rows only fit there if a row is ~22px tall, and a real row is 48: every row
51
+ * carries its type's DESCRIPTION, which wraps to a second line at any width this dialog will
52
+ * ever open at. That text has been in the list since 2026-07-11, seven weeks BEFORE the floor
53
+ * was measured. So the sweep sized the card against a list half the height of the one on
54
+ * screen, and the coupling it inferred from the wrapping TITLE, though real, is not what binds.
55
+ *
56
+ * WHAT THE RE-MEASURE SAYS. 4,050 layouts - 675 sizes (280-520 x 160-420 in 10px steps) x three
57
+ * description lengths (p25 / p50 / p75 over the 108 active types) x two base font sizes (14 and
58
+ * 16px) - same DOM, same compiled CSS. The structure is identical at both font sizes:
59
+ *
60
+ * not trapped (buttons on one line, pinned chrome unclipped, card not overflowing) 300 x 190
61
+ * >= 1 full list row visible 330 x 330
62
+ * >= 2 full list rows visible 340 x 420, and UNREACHABLE below 410
63
+ * wide once a description runs to p75
64
+ *
65
+ * 400 x 240 satisfies NEITHER - fifty pixels too tall to be about escapability, ninety too short
66
+ * to be about legibility. A 400 x 240 tile leaves 77px of list; two rows and their group heading
67
+ * need 126.
68
+ *
69
+ * SO THE FLOOR ANSWERS THE ONLY QUESTION A FLOOR CAN ANSWER HERE: can the reader get out of this
70
+ * card. The list is `overflow-y: auto` with `min-height: 0` and scrolls at every size, so "how
71
+ * much of it do I see at once" is not a thing a gate decides - scrolling handles it. What
72
+ * scrolling cannot handle is a card that CLIPS its own buttons, and that is precisely the pair
73
+ * of questions that hold from 300 x 190 down.
74
+ *
75
+ * 320 x 220 is that floor with one sweep step of margin on both dimensions - and it is also,
76
+ * exactly, the absolute floor the FIRST sweep reported before inflating it for the coupling.
77
+ * Two independent measurements agreeing on the escapability floor is the part of the original
78
+ * that survived. The margin is not decoration: both sweeps used one font stack and one English
79
+ * title, and every host localizes it.
80
+ *
81
+ * THIS IS THE ARGUMENT THE EXCEL PANE ALREADY MAKES, which is why the two hosts now differ by a
82
+ * card rather than by a philosophy - see shouldOpenInlineChooserOnGenerate below, whose whole
83
+ * reason for having no size clause is that a scrolling panel cannot trap anyone. The modal's
84
+ * list scrolls too; its CARD is the part that clips, and this floor is about the card.
85
+ *
86
+ * ERRING HIGH IS STILL THE CHEAP DIRECTION where it is genuinely cheap - below the floor the
87
+ * host generates immediately, which is what it did before this feature existed, so a tile
88
+ * wrongly judged too small costs a feature while one wrongly judged big enough costs a dialog
89
+ * with its buttons off the card. What the re-measure changes is the band over which that trade
90
+ * was being made blind: at 400 x 240 the chooser was withheld from tiles that show MORE of the
91
+ * list than tiles it was being offered on.
60
92
  */
61
- export declare const CHOOSER_MIN_WIDTH_PX = 400;
62
- export declare const CHOOSER_MIN_HEIGHT_PX = 240;
93
+ export declare const CHOOSER_MIN_WIDTH_PX = 320;
94
+ export declare const CHOOSER_MIN_HEIGHT_PX = 220;
63
95
  /**
64
96
  * Is there room to DRAW the chooser here?
65
97
  *
@@ -99,13 +131,23 @@ export declare function shouldOpenChooserOnGenerate(i: ChooserGateInput): boolea
99
131
  * a card that CLIPS, so past a certain smallness its buttons are simply not on screen and the
100
132
  * reader is trapped. A panel that flows inside a scrolling pane, with a wrapping button row,
101
133
  * cannot reach that state: swept across 63 pane sizes down to 200x120, every one stayed usable
102
- * - the footer wrapped from one line to three (38px to 86px) and stayed inside the panel, and
103
- * the list kept four or more rows because it carries its own max-height and scrolls.
134
+ * - the footer wrapped from one line to three (38px to 86px) and stayed inside the panel.
135
+ *
136
+ * So a size clause here would not protect anybody. Two hosts, two layouts, two honest answers -
137
+ * written next to each other so the difference reads as a decision rather than as one of them
138
+ * having forgotten.
139
+ *
140
+ * TWO CLAIMS THIS COMMENT USED TO MAKE HAVE BEEN WITHDRAWN (2026-09-04), because the modal's
141
+ * re-measure discredits the sweep they came from rather than this function:
104
142
  *
105
- * So a size clause here would not protect anybody; it would only switch the feature off for a
106
- * default task pane, which is narrower than the modal's floor. Two hosts, two layouts, two
107
- * honest answers - written next to each other so the difference reads as a decision rather than
108
- * as one of them having forgotten.
143
+ * * "a default task pane is narrower than the modal's floor" - it no longer is. The floor moved
144
+ * to 320x220 and an ordinary task pane clears it, so the two gates now agree on the pane that
145
+ * used to be the whole argument. The asymmetry survives only below the card's drawable
146
+ * minimum, which is the only place it ever described something real.
147
+ * * "the list kept four or more rows" - measured the same way the modal's rows were, which is
148
+ * to say without the DESCRIPTION every row carries. Whatever that number is, it is not four,
149
+ * and no claim is made here in its place. It was never the reason for having no size clause:
150
+ * the panel scrolls and the footer wraps, and THAT is the reason.
109
151
  */
110
152
  export declare function shouldOpenInlineChooserOnGenerate(i: {
111
153
  enabled: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bicharts/chart-host",
3
- "version": "0.5.69",
3
+ "version": "0.5.71",
4
4
  "description": "Run a BIC-generated D3 chart in any web host: compiles the generated render() function, applies the shared option defaults, resolves mark clicks (through tooltip overlays), owns the selection affordance, and translates row indices between cross-filtered charts. The same contract the BIC Power BI visual implements, minus Power BI. React bindings at @bicharts/chart-host/react.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",