@bicharts/chart-host 0.5.20 → 0.5.22

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.
@@ -32,6 +32,7 @@ var ANIM_MAX_IDEAL_FRAMES_MAX = 500;
32
32
  var COLOR_SCALE_SELF_CLAMP_PCT_DEFAULT = 95;
33
33
  var COLOR_SCALE_SELF_CLAMP_PCT_MIN = 50;
34
34
  var COLOR_SCALE_SELF_CLAMP_PCT_MAX = 100;
35
+ var FLIP_MODE_DEFAULT = "both";
35
36
 
36
37
  // src/defaults.ts
37
38
  var clamp = (n, lo, hi) => Math.max(lo, Math.min(hi, n));
@@ -102,11 +103,34 @@ function resolveOptions(p2) {
102
103
  // value as "independent" and hand every deck twelve control strips. Absent means
103
104
  // synced; only an explicit false switches it.
104
105
  flipSync: p2.flipSync === void 0 || p2.flipSync === null ? true : !!p2.flipSync,
106
+ // WHERE the controls live, which is a different question from whether the cards move
107
+ // together (Joel 2026-08-13: "the ability to flip individual cards shouldn't necessarily
108
+ // stop being able to flip all together too"). Resolution order matters and is the whole
109
+ // back-compat story:
110
+ // 1. an explicit, recognised flipMode wins;
111
+ // 2. otherwise DERIVE from flipSync, so a chart generated before this option existed
112
+ // behaves exactly as it did - true -> "all", false -> "single";
113
+ // 3. and a caller that sends neither gets the default.
114
+ // Deriving rather than defaulting is the point: a cached chart must not change behaviour
115
+ // because a newer client shipped, and "both" would have done exactly that to every deck
116
+ // already in a report.
117
+ flipMode: (() => {
118
+ const m2 = (p2.flipMode == null ? "" : String(p2.flipMode)).toLowerCase();
119
+ if (m2 === "single" || m2 === "all" || m2 === "both") return m2;
120
+ if (p2.flipSync === false) return "single";
121
+ if (p2.flipSync === true) return "all";
122
+ return FLIP_MODE_DEFAULT;
123
+ })(),
105
124
  // 0 is MEANINGFUL here (manual only) and is the default, so numberOr — not
106
125
  // `|| DEFAULT` — for the same reason animLoopDelaySec uses it. Clamping stays
107
126
  // chart-side: the archetype already clamps 500..120000 and two clamps in two
108
127
  // repositories is how they end up disagreeing.
109
- flipIntervalMs: Math.max(0, numberOr(p2.flipIntervalMs, 0))
128
+ flipIntervalMs: Math.max(0, numberOr(p2.flipIntervalMs, 0)),
129
+ // `raw || undefined`, the same idiom as the colour-scale endpoints and the map fills:
130
+ // blank must arrive as ABSENT, not as an empty string, because the chart's fallback is
131
+ // `options.cardBackgroundColor || <its own choice>` and "" would satisfy a truthiness
132
+ // test in some hands while painting nothing in others.
133
+ cardBackgroundColor: p2.cardBackgroundColor || void 0
110
134
  };
111
135
  }
112
136
 
@@ -996,6 +1020,11 @@ var ESM_EXPORT_DECL = /^([ \t]*)export[ \t]+(?=(?:async[ \t]+)?function\b|const\
996
1020
  function stripEsmExports(code) {
997
1021
  return String(code || "").replace(ESM_EXPORT_CLAUSE, "").replace(ESM_EXPORT_DECL, "$1");
998
1022
  }
1023
+ function writableD3(d3) {
1024
+ if (d3 == null || typeof d3 !== "object") return d3;
1025
+ if (Object.isExtensible(d3)) return d3;
1026
+ return { ...d3 };
1027
+ }
999
1028
  function compileRenderFn(code, win, doc, d3) {
1000
1029
  const body = stripEsmExports(code) + "\n;return (typeof render === 'function') ? render : null;";
1001
1030
  let factory;
@@ -1008,7 +1037,7 @@ function compileRenderFn(code, win, doc, d3) {
1008
1037
  "[@bicharts/chart-host] the generated code could not be COMPILED, so nothing was drawn. This path evaluates the chart as a code string, which cannot contain ES-module syntax" + (modular ? " \u2014 and this code still has `import`/`export` in it after the export clause was stripped. Either request the plain form from the generator, or `import` the module yourself and pass the render function directly." : ".") + " Original error: " + msg
1009
1038
  );
1010
1039
  }
1011
- const fn = factory.call(null, null, null, null, win, doc, d3);
1040
+ const fn = factory.call(null, null, null, null, win, doc, writableD3(d3));
1012
1041
  if (typeof fn !== "function") throw new Error("generated code did not define render(container, data, options)");
1013
1042
  return fn;
1014
1043
  }
@@ -1248,6 +1277,7 @@ export {
1248
1277
  COLOR_SCALE_SELF_CLAMP_PCT_DEFAULT,
1249
1278
  COLOR_SCALE_SELF_CLAMP_PCT_MIN,
1250
1279
  COLOR_SCALE_SELF_CLAMP_PCT_MAX,
1280
+ FLIP_MODE_DEFAULT,
1251
1281
  resolveOptions,
1252
1282
  geoAssetFor,
1253
1283
  loadGeo,
package/dist/index.mjs CHANGED
@@ -17,6 +17,7 @@ import {
17
17
  CONTAINER_SLOT_XF_CLEAR,
18
18
  DIM_OPACITY_DEFAULT,
19
19
  DIM_OPACITY_VAR,
20
+ FLIP_MODE_DEFAULT,
20
21
  GEO_POINT_PRECISIONS,
21
22
  HOST_CONTAINER_CLASS,
22
23
  HOST_CONTRACT_VERSION,
@@ -41,7 +42,7 @@ import {
41
42
  requiredD3Plugins,
42
43
  resolveOptions,
43
44
  stripEsmExports
44
- } from "./chunk-TBRWWGJW.mjs";
45
+ } from "./chunk-65LTZEX6.mjs";
45
46
  import "./chunk-A2GMXZP7.mjs";
46
47
 
47
48
  // src/trivial.ts
@@ -338,6 +339,7 @@ export {
338
339
  CONTAINER_SLOT_XF_CLEAR,
339
340
  DIM_OPACITY_DEFAULT,
340
341
  DIM_OPACITY_VAR,
342
+ FLIP_MODE_DEFAULT,
341
343
  GEO_POINT_PRECISIONS,
342
344
  HOST_CONTAINER_CLASS,
343
345
  HOST_CONTRACT_VERSION,
package/dist/react.mjs CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  createChartHost,
5
5
  geoFromCache,
6
6
  loadGeo
7
- } from "./chunk-TBRWWGJW.mjs";
7
+ } from "./chunk-65LTZEX6.mjs";
8
8
  import "./chunk-A2GMXZP7.mjs";
9
9
 
10
10
  // src/react.tsx
@@ -32,6 +32,8 @@ export declare const COLOR_SCALE_SELF_CLAMP_PCT_DEFAULT = 95;
32
32
  export declare const COLOR_SCALE_SELF_CLAMP_PCT_MIN = 50;
33
33
  export declare const COLOR_SCALE_SELF_CLAMP_PCT_MAX = 100;
34
34
  export type TimelineStyle = "" | "line" | "boxes";
35
+ export type FlipMode = "" | "single" | "all" | "both";
36
+ export declare const FLIP_MODE_DEFAULT: FlipMode;
35
37
  export type ColorScaleScope = "" | "frame" | "self";
36
38
  export interface RenderOptions {
37
39
  width: number;
@@ -79,5 +81,7 @@ export interface RenderOptions {
79
81
  animTimelineStyle?: TimelineStyle;
80
82
  flipSync?: boolean;
81
83
  flipIntervalMs?: number;
84
+ flipMode?: FlipMode;
85
+ cardBackgroundColor?: string;
82
86
  onSelect?: (rowIdxs: number[]) => void;
83
87
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bicharts/chart-host",
3
- "version": "0.5.20",
3
+ "version": "0.5.22",
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",