@bicharts/chart-host 0.5.40 → 0.5.42
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.
|
@@ -112,7 +112,7 @@ function resolveOptions(p2) {
|
|
|
112
112
|
// synced; only an explicit false switches it.
|
|
113
113
|
flipSync: p2.flipSync === void 0 || p2.flipSync === null ? true : !!p2.flipSync,
|
|
114
114
|
// WHERE the controls live, which is a different question from whether the cards move
|
|
115
|
-
// together (
|
|
115
|
+
// together (2026-08-13: "the ability to flip individual cards shouldn't necessarily
|
|
116
116
|
// stop being able to flip all together too"). Resolution order matters and is the whole
|
|
117
117
|
// back-compat story:
|
|
118
118
|
// 1. an explicit, recognised flipMode wins;
|
package/dist/index.mjs
CHANGED
|
@@ -47,7 +47,7 @@ import {
|
|
|
47
47
|
requiredD3Plugins,
|
|
48
48
|
resolveOptions,
|
|
49
49
|
stripEsmExports
|
|
50
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-BMYEYUEN.mjs";
|
|
51
51
|
import "./chunk-A2GMXZP7.mjs";
|
|
52
52
|
|
|
53
53
|
// src/trivial.ts
|
|
@@ -574,6 +574,37 @@ function qualifyGroupHeadingFor(row, state) {
|
|
|
574
574
|
return null;
|
|
575
575
|
}
|
|
576
576
|
|
|
577
|
+
// src/qualifyLaunch.ts
|
|
578
|
+
var qualifyPick = (chartType) => ({ kind: "pick", chartType });
|
|
579
|
+
var qualifyAuto = () => ({ kind: "auto" });
|
|
580
|
+
var qualifyCancel = () => ({ kind: "cancel" });
|
|
581
|
+
function launchGenerates(outcome) {
|
|
582
|
+
return outcome.kind === "pick" || outcome.kind === "auto";
|
|
583
|
+
}
|
|
584
|
+
function launchFavorStyle(outcome, autoSentinel) {
|
|
585
|
+
return outcome.kind === "pick" ? outcome.chartType : autoSentinel;
|
|
586
|
+
}
|
|
587
|
+
var CHOOSER_MIN_WIDTH_PX = 400;
|
|
588
|
+
var CHOOSER_MIN_HEIGHT_PX = 240;
|
|
589
|
+
function chooserFitsViewport(width, height) {
|
|
590
|
+
if (!isFinite(width) || !isFinite(height)) return false;
|
|
591
|
+
return width >= CHOOSER_MIN_WIDTH_PX && height >= CHOOSER_MIN_HEIGHT_PX;
|
|
592
|
+
}
|
|
593
|
+
function shouldOpenChooserOnGenerate(i) {
|
|
594
|
+
if (!i.enabled) return false;
|
|
595
|
+
if (!i.hasData) return false;
|
|
596
|
+
return chooserFitsViewport(i.width, i.height);
|
|
597
|
+
}
|
|
598
|
+
function canConfirmLaunch(selected) {
|
|
599
|
+
return typeof selected === "string" && selected.trim() !== "";
|
|
600
|
+
}
|
|
601
|
+
function confirmLaunch(selected) {
|
|
602
|
+
return canConfirmLaunch(selected) ? qualifyPick(String(selected).trim()) : qualifyCancel();
|
|
603
|
+
}
|
|
604
|
+
function qualifyFailureFallsOpen(viaGenerate) {
|
|
605
|
+
return viaGenerate === true;
|
|
606
|
+
}
|
|
607
|
+
|
|
577
608
|
// src/selectionCard.ts
|
|
578
609
|
var SYNTHETIC_PREFIX = "__";
|
|
579
610
|
var NUMERIC_DATATYPE = /int|double|decimal|single|float|number|currency|money/i;
|
|
@@ -753,6 +784,8 @@ export {
|
|
|
753
784
|
ANIM_PLAY_SPEED_MAX,
|
|
754
785
|
ANIM_PLAY_SPEED_MIN,
|
|
755
786
|
AXIS_FILTER_CLASS,
|
|
787
|
+
CHOOSER_MIN_HEIGHT_PX,
|
|
788
|
+
CHOOSER_MIN_WIDTH_PX,
|
|
756
789
|
COLOR_SCALE_SELF_CLAMP_PCT_DEFAULT,
|
|
757
790
|
COLOR_SCALE_SELF_CLAMP_PCT_MAX,
|
|
758
791
|
COLOR_SCALE_SELF_CLAMP_PCT_MIN,
|
|
@@ -777,30 +810,40 @@ export {
|
|
|
777
810
|
bareBase64,
|
|
778
811
|
buildRenderPayload,
|
|
779
812
|
buildReviewWire,
|
|
813
|
+
canConfirmLaunch,
|
|
780
814
|
captureSvgSnapshot,
|
|
781
815
|
chartOwnsTimeline,
|
|
816
|
+
chooserFitsViewport,
|
|
782
817
|
clearGeoCache,
|
|
783
818
|
compileRenderFn,
|
|
784
819
|
compileTrivialSource,
|
|
785
820
|
computeSelectionCard,
|
|
821
|
+
confirmLaunch,
|
|
786
822
|
createChartHost,
|
|
787
823
|
createMarkResolver,
|
|
788
824
|
ensureCrossfilterHitTargets,
|
|
789
825
|
explainRenderFailure,
|
|
790
826
|
geoAssetFor,
|
|
791
827
|
geoFromCache,
|
|
828
|
+
launchFavorStyle,
|
|
829
|
+
launchGenerates,
|
|
792
830
|
loadGeo,
|
|
793
831
|
newQualifyGroupState,
|
|
794
832
|
normaliseAggregation,
|
|
795
833
|
periodTickSuppressesFeedback,
|
|
796
834
|
planTrivialChart,
|
|
835
|
+
qualifyAuto,
|
|
836
|
+
qualifyCancel,
|
|
837
|
+
qualifyFailureFallsOpen,
|
|
797
838
|
qualifyGroupHeadingFor,
|
|
839
|
+
qualifyPick,
|
|
798
840
|
rasterizeSvgToPngDataUrl,
|
|
799
841
|
registerCityTable,
|
|
800
842
|
registerGeo,
|
|
801
843
|
registerGeoAsset,
|
|
802
844
|
requiredD3Plugins,
|
|
803
845
|
resolveOptions,
|
|
846
|
+
shouldOpenChooserOnGenerate,
|
|
804
847
|
shouldReview,
|
|
805
848
|
stripEsmExports,
|
|
806
849
|
svgNaturalSize,
|
package/dist/react.mjs
CHANGED
package/dist/types/index.d.ts
CHANGED
|
@@ -12,5 +12,6 @@ export { captureSvgSnapshot, svgToDataUrl, svgNaturalSize, rasterizeSvgToPngData
|
|
|
12
12
|
export { shouldReview, buildReviewWire, bareBase64, actionFor, type ReviewGate, type ReviewWire, type ReviewVerdict, type ReviewAction } from "./review";
|
|
13
13
|
export { askApplyImprovements, type ReviewDialogOptions, type ReviewDialogText } from "./reviewDialog";
|
|
14
14
|
export { qualifyGroupHeadingFor, newQualifyGroupState, type QualifyGroupRow, type QualifyGroupState, type QualifyGroupHeading, } from "./qualifyGroups";
|
|
15
|
+
export { qualifyPick, qualifyAuto, qualifyCancel, launchGenerates, launchFavorStyle, chooserFitsViewport, shouldOpenChooserOnGenerate, canConfirmLaunch, confirmLaunch, qualifyFailureFallsOpen, CHOOSER_MIN_WIDTH_PX, CHOOSER_MIN_HEIGHT_PX, type QualifyLaunchOutcome, type ChooserGateInput, } from "./qualifyLaunch";
|
|
15
16
|
export { computeSelectionCard, normaliseAggregation, type SelectionCardModel, type SelectionCardLine, type SelectionCardOptions, } from "./selectionCard";
|
|
16
17
|
export { ensureCrossfilterHitTargets, type HitTargetReport } from "./hitTargets";
|
package/dist/types/payload.d.ts
CHANGED
|
@@ -44,7 +44,7 @@ export interface RenderPayload {
|
|
|
44
44
|
* reason ("only 95.5% of values are country identifiers") and no way to say it.
|
|
45
45
|
*
|
|
46
46
|
* Present whenever a point binding was attempted and something was refused, whether or not
|
|
47
|
-
* a map came out of it.
|
|
47
|
+
* a map came out of it. 2026-08-02: "be sure to provide feedback in the output that
|
|
48
48
|
* helps call out exceptions / decisions like this, if possible."
|
|
49
49
|
*/
|
|
50
50
|
geoPointRefused?: string[];
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/** How the reader left the chooser. Three outcomes, never two - see the note above. */
|
|
2
|
+
export type QualifyLaunchOutcome =
|
|
3
|
+
/** A named type. Rides the host's explicit-pick lane for exactly one generation. */
|
|
4
|
+
{
|
|
5
|
+
kind: "pick";
|
|
6
|
+
chartType: string;
|
|
7
|
+
}
|
|
8
|
+
/** "Choose for me." Generates with NO preference expressed. */
|
|
9
|
+
| {
|
|
10
|
+
kind: "auto";
|
|
11
|
+
}
|
|
12
|
+
/** Backed out. Nothing is generated and no preference is recorded. */
|
|
13
|
+
| {
|
|
14
|
+
kind: "cancel";
|
|
15
|
+
};
|
|
16
|
+
export declare const qualifyPick: (chartType: string) => QualifyLaunchOutcome;
|
|
17
|
+
export declare const qualifyAuto: () => QualifyLaunchOutcome;
|
|
18
|
+
export declare const qualifyCancel: () => QualifyLaunchOutcome;
|
|
19
|
+
/** Does this outcome start a generation? False for cancel ALONE. */
|
|
20
|
+
export declare function launchGenerates(outcome: QualifyLaunchOutcome): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* The value a host should put in its explicit-pick field for this outcome.
|
|
23
|
+
*
|
|
24
|
+
* GENERIC OVER THE SENTINEL BECAUSE THE HOSTS DISAGREE ABOUT WHAT "AUTO" IS SPELLED AS, and
|
|
25
|
+
* that disagreement is real rather than sloppy: one host's field is a nullable string whose
|
|
26
|
+
* null means "the picker decides", another's is a plain string whose empty value is the wire
|
|
27
|
+
* form. Neither can adopt the other's without changing a wire contract. So the sentinel is
|
|
28
|
+
* passed IN and this function only decides WHICH of the two values applies - which is the part
|
|
29
|
+
* that must not differ.
|
|
30
|
+
*
|
|
31
|
+
* Cancel maps to the sentinel too, defensively: a caller that ignores `launchGenerates` and
|
|
32
|
+
* reads this anyway gets "no preference" rather than a stale pick. It should still not generate.
|
|
33
|
+
*/
|
|
34
|
+
export declare function launchFavorStyle<T>(outcome: QualifyLaunchOutcome, autoSentinel: T): string | T;
|
|
35
|
+
/**
|
|
36
|
+
* THE SMALLEST TILE THE CHOOSER IS USABLE IN, measured rather than guessed (2026-09-01).
|
|
37
|
+
*
|
|
38
|
+
* A sweep of 168 tile sizes in headless Chromium, rendering the real card DOM and CSS, asking
|
|
39
|
+
* three questions of each: do the three launch buttons sit on one line inside the card, are at
|
|
40
|
+
* least two list rows visible, and is nothing in the pinned chrome clipped. The measured floor
|
|
41
|
+
* is 320 x 220 - but the two dimensions are COUPLED, because under 400 px the card's title
|
|
42
|
+
* wraps to a second line and eats the list's height: at 320-340 wide the height floor rises to
|
|
43
|
+
* 280, at 360-380 to 260, and only at 400+ does 220 hold.
|
|
44
|
+
*
|
|
45
|
+
* 400 x 240 is that envelope with one sweep step of margin on the height. The margin is not
|
|
46
|
+
* decoration: the measurement used one font stack and one string, and every host localizes the
|
|
47
|
+
* title, so a longer translation wraps sooner than the sample did.
|
|
48
|
+
*
|
|
49
|
+
* ERRING HIGH IS THE CHEAP DIRECTION. Below the floor the host generates immediately, which is
|
|
50
|
+
* the behaviour it had before the chooser existed - so a tile wrongly judged too small costs a
|
|
51
|
+
* feature, while one wrongly judged big enough costs a dialog whose buttons are off the card.
|
|
52
|
+
*/
|
|
53
|
+
export declare const CHOOSER_MIN_WIDTH_PX = 400;
|
|
54
|
+
export declare const CHOOSER_MIN_HEIGHT_PX = 240;
|
|
55
|
+
/**
|
|
56
|
+
* Is there room to DRAW the chooser here?
|
|
57
|
+
*
|
|
58
|
+
* MEASURE THE REAL SURFACE, never a size the host reports outward. Where a host lets an author
|
|
59
|
+
* state a viewport for generation purposes, that stated size is a claim about a tile that does
|
|
60
|
+
* not exist yet; the dialog has to fit the pixels actually on screen.
|
|
61
|
+
*/
|
|
62
|
+
export declare function chooserFitsViewport(width: number, height: number): boolean;
|
|
63
|
+
export interface ChooserGateInput {
|
|
64
|
+
/** The host's opt-out setting. False = the reader wants one-click Generate back. */
|
|
65
|
+
enabled: boolean;
|
|
66
|
+
/** Real drawable width, in CSS pixels. */
|
|
67
|
+
width: number;
|
|
68
|
+
/** Real drawable height, in CSS pixels. */
|
|
69
|
+
height: number;
|
|
70
|
+
/**
|
|
71
|
+
* Is there anything to qualify? A chooser over an empty binding can only say "bind
|
|
72
|
+
* something first", which the host's own Generate path already says better and without
|
|
73
|
+
* a round-trip.
|
|
74
|
+
*/
|
|
75
|
+
hasData: boolean;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Should pressing Generate open the chooser instead of generating?
|
|
79
|
+
*
|
|
80
|
+
* FALSE IS ALWAYS SAFE and that is the design: every false answer here lands on the behaviour
|
|
81
|
+
* the host had before this feature existed - press Generate, get a chart. So the gate can be
|
|
82
|
+
* conservative without stranding anybody, and a new reason to decline can be added later
|
|
83
|
+
* without auditing what it breaks.
|
|
84
|
+
*/
|
|
85
|
+
export declare function shouldOpenChooserOnGenerate(i: ChooserGateInput): boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Is the confirm button live?
|
|
88
|
+
*
|
|
89
|
+
* A SEPARATE QUESTION FROM "is a type selected", because it is the answer to a UI state and the
|
|
90
|
+
* host asks it on every selection change. Kept here so both hosts agree that selecting a row is
|
|
91
|
+
* what arms confirm - the alternative, arming it always and validating on click, produces a
|
|
92
|
+
* button that looks ready and then refuses, which is the interaction this flow replaced.
|
|
93
|
+
*/
|
|
94
|
+
export declare function canConfirmLaunch(selected: string | null | undefined): boolean;
|
|
95
|
+
/**
|
|
96
|
+
* The outcome of pressing confirm with `selected` highlighted.
|
|
97
|
+
*
|
|
98
|
+
* Returns CANCEL rather than auto when nothing is selected, and the choice matters: confirm
|
|
99
|
+
* with an empty selection is a state the UI should not allow, so if it happens the honest
|
|
100
|
+
* reading is "this click means nothing", not "this click means spend a credit". The host's
|
|
101
|
+
* disabled state is the first guard; this is the second.
|
|
102
|
+
*/
|
|
103
|
+
export declare function confirmLaunch(selected: string | null | undefined): QualifyLaunchOutcome;
|
|
104
|
+
/**
|
|
105
|
+
* WHAT A FAILED QUALIFY MEANS depends on which door the reader came through, and this is the
|
|
106
|
+
* one place that says so.
|
|
107
|
+
*
|
|
108
|
+
* Opened from Generate, the reader asked for a CHART: the chooser is an offer along the way, so
|
|
109
|
+
* when qualify errors or times out the flow proceeds to generate and the degradation is logged
|
|
110
|
+
* rather than shown. Opened from a "what fits?" affordance, the reader asked a QUESTION: failing
|
|
111
|
+
* open there would spend a credit nobody requested, so the error is shown and nothing runs.
|
|
112
|
+
*
|
|
113
|
+
* This is the whole reason the two doors are distinguishable at all. Everything else about them
|
|
114
|
+
* - the list, the buttons, the outcomes - is deliberately identical.
|
|
115
|
+
*/
|
|
116
|
+
export declare function qualifyFailureFallsOpen(viaGenerate: boolean): boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bicharts/chart-host",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.42",
|
|
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",
|