@bicharts/chart-host 0.6.107 → 0.6.109

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.
@@ -1,4 +1,5 @@
1
- import { type RenderOptions } from "./contract";
1
+ import { type RenderOptions, type HostSelectionFact } from "./contract";
2
+ export declare function cleanHostSelection(v: unknown): HostSelectionFact | undefined;
2
3
  export type ResolveOptionsInput = {
3
4
  [K in keyof RenderOptions]?: any;
4
5
  };
@@ -62,8 +62,9 @@ export interface Filter {
62
62
  readonly reason: FilterChangeReason | null;
63
63
  /** Bumped on every change: a cheap identity for memoising on the filter's state. */
64
64
  readonly version: number;
65
- /** Select these rows' keys (replacing the selection). An empty list clears. */
66
- selectRows(rows: readonly Record<string, unknown>[], reason?: FilterChangeReason): void;
65
+ /** Select these rows' keys (replacing the selection). An empty list clears. `keep` adds keys held already that these
66
+ * rows cannot name (keys another filter hid from the chart that made the selection): they stay selected. */
67
+ selectRows(rows: readonly Record<string, unknown>[], reason?: FilterChangeReason, keep?: readonly FilterKey[]): void;
67
68
  /** Select keys by value: one value per key (a one-column filter) or one array per key. */
68
69
  set(keys: readonly unknown[] | readonly FilterKey[] | unknown, reason?: FilterChangeReason): void;
69
70
  /** Clear the selection (and every bound chart's marks). */
@@ -119,9 +120,8 @@ export declare function createFilter(columns: string | readonly string[], opts?:
119
120
  export declare function createFilterScope(): FilterScope;
120
121
  export interface FilterBinding {
121
122
  /**
122
- * Call after the chart is handed new data. A selection whose key is still drawn is repainted;
123
- * one whose key is gone is cleared (reason "data") when this chart made it. An empty payload is
124
- * treated as data still arriving, not as the key being gone.
123
+ * Call after the chart is handed new data. The selection is repainted where its keys are drawn now, and a key the new
124
+ * rows do not carry stays selected (the chart is told how many through hostSelection.hidden): new data never clears it.
125
125
  */
126
126
  reconcile(): void;
127
127
  /** Repaint the filter's selection onto the chart's marks. */
@@ -0,0 +1,12 @@
1
+ export interface FocusMemory {
2
+ sig: string;
3
+ nth: number;
4
+ start: number | null;
5
+ end: number | null;
6
+ dir: "forward" | "backward" | "none" | null;
7
+ }
8
+ /** The focused element inside the container and its caret, or null when focus is elsewhere (or on the container). */
9
+ export declare function rememberFocus(container: HTMLElement): FocusMemory | null;
10
+ /** Give focus back to the same element of the new draw, with its caret. Nothing when the chart already moved focus into
11
+ * itself, or when the new draw has no such element. Returns whether focus was restored. */
12
+ export declare function restoreFocus(container: HTMLElement, memory: FocusMemory | null): boolean;
@@ -2,6 +2,11 @@ import { type RenderOptions, type ViewStateProvider } from "./contract";
2
2
  import { type ResolveOptionsInput } from "./defaults";
3
3
  import { type SelectionRule, type SelectionPaintMode } from "./selection";
4
4
  /** What onSelectionPaint reports: the declared rule, how this paint decided, and how many marks it lit. */
5
+ /** What a selection change carries besides its rows (1.21.0): `keepHidden` when the chart's set is what the reader holds among
6
+ * the rows in view, so a subscriber that holds keys the data no longer carries keeps them. */
7
+ export interface SelectionChangeMeta {
8
+ keepHidden?: boolean;
9
+ }
5
10
  export interface SelectionPaintReport {
6
11
  rule: SelectionRule;
7
12
  mode: SelectionPaintMode;
@@ -275,6 +280,16 @@ export interface ChartHostConfig {
275
280
  * `selects` and the group itself. Never throws through: an answer that throws counts as reached.
276
281
  */
277
282
  selectionReachesPage?: () => boolean;
283
+ /**
284
+ * WHETHER A CLICK ON A MARK SELECTS ANYTHING. False: nothing listens to this chart's selection - no
285
+ * page filter, no group sibling, no callback - so its marks are drawn inert: no pointer cursor (over the chart's own
286
+ * inline one), no hover dimming of the others, and the reader's click, or a selection the chart dispatches itself,
287
+ * lights and dims nothing. A selection the page hands in (selection.highlight) still paints. Read at every click and
288
+ * every paint, so a binding added later counts at once. Absent: true, which every host but React relies on (a Power
289
+ * BI click always reaches its selection manager; an Excel click always opens a selection card). An answer that
290
+ * throws counts as true.
291
+ */
292
+ marksSelect?: () => boolean;
278
293
  }
279
294
  export interface ChartHost {
280
295
  /** Replace the notes drawn on marks (see ChartHostConfig.annotations); redraws them at once. */
@@ -304,7 +319,7 @@ export interface ChartHost {
304
319
  selection: {
305
320
  /** Subscribe to cross-filter changes (mark clicks + the chart's own
306
321
  * llm-xfilter-refresh dispatches). rowIdxs = [] means cleared. */
307
- onChange(cb: (rowIdxs: number[], source: string) => void): () => void;
322
+ onChange(cb: (rowIdxs: number[], source: string, meta?: SelectionChangeMeta) => void): () => void;
308
323
  /** Clear the chart's own selection (calls __llmXfClear when the chart set it). */
309
324
  clear(): void;
310
325
  /**
@@ -323,6 +338,12 @@ export interface ChartHost {
323
338
  * republish what the other just sent and fight itself.
324
339
  */
325
340
  highlight(rowIdxs: number[]): void;
341
+ /**
342
+ * How many of the selection's identities the data on screen does not carry (1.21.0): a filter keyed by value that
343
+ * another filter narrowed knows, this host does not. Told to the chart (RenderOptions.hostSelection and the
344
+ * CONTAINER_SLOT_HOST_SELECTION slot), so a checkbox column can say "2 selected, 2 hidden". A clear resets it.
345
+ */
346
+ setHidden?(count: number): void;
326
347
  readonly current: number[] | null;
327
348
  };
328
349
  animation: {
@@ -1,5 +1,5 @@
1
- export { HOST_CONTRACT_VERSION, GEO_POINT_PRECISIONS, MARK_CLASS, LEGEND_MARK_CLASS, AXIS_FILTER_CLASS, ROW_IDX_ATTR, LIFT_SELECTED_CLASS, CONTROL_CLASS, NO_ROW_MARKS_ATTR, NOTE_STYLE_ATTR, SELECTION_RULE_ATTR, SELECTION_RULE_CLICKED_MARKS, MARK_KEY_ATTR, CONTAINER_SLOT_CLICKED_MARKS, SNAPSHOT_SVG_ATTR, XFILTER_REFRESH_EVENT, CONTAINER_SLOT_ANIM_STOP, CONTAINER_SLOT_XF_CLEAR, CONTAINER_SLOT_INITIAL_XF_MARK, CONTAINER_SLOT_UI_STATE, CONTAINER_SLOT_SCROLL, VIEW_ONLY_UI_STATE_KEYS, withoutViewOnlyKeys, HOST_CONTAINER_CLASS, SELECTION_ACTIVE_CLASS, MARK_SELECTED_CLASS, ACTIVE_TICK_CLASS, DIM_OPACITY_VAR, DIM_OPACITY_DEFAULT, DIM_OPACITY_MIN, chartOwnsTimeline, periodTickSuppressesFeedback, ANIM_PLAY_SPEED_DEFAULT, ANIM_PLAY_SPEED_MIN, ANIM_PLAY_SPEED_MAX, ANIM_LOOP_DELAY_DEFAULT, ANIM_LOOP_DELAY_MIN, ANIM_MAX_IDEAL_FRAMES_DEFAULT, ANIM_MAX_IDEAL_FRAMES_MIN, ANIM_MAX_IDEAL_FRAMES_MAX, ANIMATION_OPTION_KEYS, COLOR_SCALE_SELF_CLAMP_PCT_DEFAULT, COLOR_SCALE_SELF_CLAMP_PCT_MIN, COLOR_SCALE_SELF_CLAMP_PCT_MAX, FLIP_MODE_DEFAULT, FLIP_INTERVAL_MIN_MS, FLIP_INTERVAL_MAX_MS, FLIP_DIRECTION_DEFAULT, APPROXIMATE_POSITIONS_DEFAULT, VALUE_AXIS_BASELINE_DEFAULT, SEASONAL_MARKERS_DEFAULT, MAX_MAP_POINTS_DEFAULT, type GeoPointPrecision, type GeoMapKind, type TimelineStyle, type FlipMode, type FlipDirection, type ApproximatePositions, type ValueAxisBaseline, type SeasonalMarkers, type ColorScaleScope, type RenderOptions, type ViewStateProvider, type ChartControlChange, type XfilterRefreshDetail, } from "./contract";
2
- export { resolveOptions, type ResolveOptionsInput } from "./defaults";
1
+ export { HOST_CONTRACT_VERSION, GEO_POINT_PRECISIONS, MARK_CLASS, LEGEND_MARK_CLASS, AXIS_FILTER_CLASS, ROW_IDX_ATTR, LIFT_SELECTED_CLASS, CONTROL_CLASS, NO_ROW_MARKS_ATTR, NOTE_STYLE_ATTR, SELECTION_RULE_ATTR, SELECTION_RULE_CLICKED_MARKS, MARK_KEY_ATTR, CONTAINER_SLOT_CLICKED_MARKS, SNAPSHOT_SVG_ATTR, XFILTER_REFRESH_EVENT, CONTAINER_SLOT_ANIM_STOP, CONTAINER_SLOT_XF_CLEAR, CONTAINER_SLOT_INITIAL_XF_MARK, CONTAINER_SLOT_UI_STATE, CONTAINER_SLOT_SCROLL, CONTAINER_SLOT_HOST_SELECTION, VIEW_ONLY_UI_STATE_KEYS, withoutViewOnlyKeys, HOST_CONTAINER_CLASS, SELECTION_ACTIVE_CLASS, MARK_SELECTED_CLASS, MARKS_INERT_CLASS, ACTIVE_TICK_CLASS, DIM_OPACITY_VAR, DIM_OPACITY_DEFAULT, DIM_OPACITY_MIN, chartOwnsTimeline, periodTickSuppressesFeedback, ANIM_PLAY_SPEED_DEFAULT, ANIM_PLAY_SPEED_MIN, ANIM_PLAY_SPEED_MAX, ANIM_LOOP_DELAY_DEFAULT, ANIM_LOOP_DELAY_MIN, ANIM_MAX_IDEAL_FRAMES_DEFAULT, ANIM_MAX_IDEAL_FRAMES_MIN, ANIM_MAX_IDEAL_FRAMES_MAX, ANIMATION_OPTION_KEYS, COLOR_SCALE_SELF_CLAMP_PCT_DEFAULT, COLOR_SCALE_SELF_CLAMP_PCT_MIN, COLOR_SCALE_SELF_CLAMP_PCT_MAX, FLIP_MODE_DEFAULT, FLIP_INTERVAL_MIN_MS, FLIP_INTERVAL_MAX_MS, FLIP_DIRECTION_DEFAULT, APPROXIMATE_POSITIONS_DEFAULT, VALUE_AXIS_BASELINE_DEFAULT, SEASONAL_MARKERS_DEFAULT, MAX_MAP_POINTS_DEFAULT, type GeoPointPrecision, type GeoMapKind, type TimelineStyle, type FlipMode, type FlipDirection, type ApproximatePositions, type ValueAxisBaseline, type SeasonalMarkers, type ColorScaleScope, type RenderOptions, type ViewStateProvider, type ChartControlChange, type XfilterRefreshDetail, type HostSelectionFact, } from "./contract";
2
+ export { resolveOptions, cleanHostSelection, type ResolveOptionsInput } from "./defaults";
3
3
  export { hostLinkServices, type HostLinkServices, type ClipboardLike } from "./hostLinks";
4
4
  export { tableToCsv, tableToXlsx, buildExportFile, exportFileName, sheetName as exportSheetName, excelNumberFormat, excelSerial, bytesToBase64, exportFormatsFor, exportTableService, browserSaveFile, EXPORT_FORMATS, XLSX_MIME, CSV_MIME, type ExportTable, type ExportColumn, type ExportColumnType, type ExportCell, type ExportFormat, type ExportFile, type SaveFileService, type ExportTableService, } from "./exportTable";
5
5
  export { OPTIONS_VOCABULARY, LIVE_OPTION_KEYS, MAX_MAP_POINTS_MIN, MAX_MAP_POINTS_MAX, LIMIT_COUNT_MAX, wireLimitCount, codeReadsOption, type OptionVocabularyEntry, type OptionTiming, type OptionWire, type OptionKey, } from "./optionsVocabulary";
@@ -9,8 +9,10 @@ export { loadGeo, geoFromCache, registerGeo, registerGeoAsset, geoAssetFor, clea
9
9
  export declare function registerCityTable(packed: string): void;
10
10
  export { buildRenderPayload, type RenderPayload, type GeoPointBinding, type GeoBinding, type GeoProvinceReport, type ProvinceJoin } from "./payload";
11
11
  export { codeReadsDatesInLocalTime, vegaSpecReadsDatesInLocalTime } from "./dateCells";
12
- export { createChartHost, compileRenderFn, stripEsmExports, requiredD3Plugins, explainRenderFailure, sessionViewStateProvider, noopViewStateProvider, assembleD3, D3_PLUGIN_PACKAGES, type ChartHost, type ChartHostConfig, type RenderFn, type SelectionPaintReport } from "./host";
12
+ export { createChartHost, compileRenderFn, stripEsmExports, requiredD3Plugins, explainRenderFailure, sessionViewStateProvider, noopViewStateProvider, assembleD3, D3_PLUGIN_PACKAGES, type ChartHost, type ChartHostConfig, type RenderFn, type SelectionPaintReport, type SelectionChangeMeta } from "./host";
13
13
  export { ANNOTATION_CLASS, ANNOTATION_LAYER_CLASS, type MarkAnnotation, type AnnotationReport } from "./annotations";
14
+ export { KEYBOARD_STAMP, KEYBOARD_CLASS, WIRED_ATTR as KEYBOARD_WIRED_ATTR, codeHasKeyboardStamp, installKeyboard, rowNameOf, type KeyboardEnv, type KeyboardHandle } from "./keyboardMarks";
15
+ export { rememberFocus, restoreFocus, type FocusMemory } from "./focusKeep";
14
16
  export type { MarkNoteLike, NoteBadgeOptions } from "./markNotes";
15
17
  export type { Controls, ControlInfo, ControlsAttachment } from "./controls";
16
18
  export { createChartGroup, toSourceRows, syncMemberSelection, type ChartGroup, type ChartGroupMember, type ChartGroupSelection, type ChartGroupChange, type ChartGroupMemberOptions, type ChartGroupSourceOptions, type ChartGroupPayload } from "./group";
@@ -0,0 +1,43 @@
1
+ export declare const KEYBOARD_STAMP = "// bic:keyboard-marks";
2
+ /** Whether the code carries the keyboard stamp in its header. */
3
+ export declare function codeHasKeyboardStamp(code: unknown): boolean;
4
+ /** On the container while its chart works from the keyboard. */
5
+ export declare const KEYBOARD_CLASS = "lch-keyboard";
6
+ /** On each element the host made focusable, so it never touches one the chart made focusable itself. */
7
+ export declare const WIRED_ATTR = "data-lch-kb";
8
+ export interface KeyboardEnv {
9
+ container: HTMLElement;
10
+ /** The elements a click selects (the host's click selector). */
11
+ markSelector: string;
12
+ /** Elements pressed with Enter: the chart's declared controls and the host's badges. */
13
+ pressSelector: string;
14
+ /** Elements never to treat as marks (the host's own layers). */
15
+ skipSelector: string;
16
+ /** True while a click on a mark selects nothing (the marks are then not made focusable). */
17
+ inert(): boolean;
18
+ /** Select a mark as a click on it would. */
19
+ select(mark: Element, mods: {
20
+ ctrl: boolean;
21
+ shift: boolean;
22
+ }): void;
23
+ /** The reader's clear: Ctrl+Shift+C on every host (Power BI's own clear-selection key), and Escape where the host
24
+ * lets it (escapeClears). */
25
+ clear(): void;
26
+ /** Whether Escape clears. False for a host whose frame uses Escape to move focus out of the chart (Power BI), so
27
+ * leaving the chart never wipes the reader's selection there. Default true. */
28
+ escapeClears?: boolean;
29
+ isSelected(mark: Element): boolean;
30
+ /** What a screen reader calls a mark that names nothing itself. */
31
+ labelOf(mark: Element): string | null;
32
+ /** A stable key for a mark across redraws (its rows). */
33
+ keyOf(mark: Element): string;
34
+ }
35
+ export interface KeyboardHandle {
36
+ /** Re-apply tab stops, roles, names and pressed state after a draw or a selection change. */
37
+ refresh(): void;
38
+ destroy(): void;
39
+ }
40
+ /** What a screen reader calls a row: its first few values, numbers in the reader's culture, internal columns left out.
41
+ * Shared so every host names a mark the same way. */
42
+ export declare function rowNameOf(columns: ReadonlyArray<unknown>, row: ReadonlyArray<unknown> | null | undefined, culture?: string): string | null;
43
+ export declare function installKeyboard(env: KeyboardEnv): KeyboardHandle;
@@ -95,7 +95,7 @@ export interface BicChartProps {
95
95
  * THE PAGE FILTER THIS CHART SELECTS - from useBicFilter("RegionCode"). A click sets it, the
96
96
  * same click or a click on empty canvas clears it, and the filter's state is painted onto the
97
97
  * marks whoever changed it: `filter.clear()` from a page button clears the marks too. New data
98
- * keeps a selection whose key is still drawn and clears (reason "data") one whose key is gone.
98
+ * keeps the selection, a key it no longer draws included; the chart is told how many are hidden.
99
99
  * The page reads `filter.value` / `filter.row` and never writes a select handler. With
100
100
  * `selects`, the filter owns what this chart shows as selected.
101
101
  */
@@ -1,7 +1,7 @@
1
1
  /*! @bicharts/chart-host — Apache-2.0. Bundled reference data: GeoNames (https://www.geonames.org/) CC BY 4.0; Natural Earth and US Census/TIGER (public domain). Full text: NOTICE in this package. */
2
2
  import {
3
3
  K
4
- } from "./chunk-SYUJ4TPX.mjs";
4
+ } from "./chunk-TH577JHI.mjs";
5
5
  import "./chunk-GHODWOAL.mjs";
6
6
 
7
7
  // src/zoomMemory/zoomMemory.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bicharts/chart-host",
3
- "version": "0.6.107",
3
+ "version": "0.6.109",
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",