@gooddata/sdk-ui-vis-commons 11.41.0-alpha.0 → 11.41.0-alpha.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.
@@ -1,4 +1,4 @@
1
- import { type IResolvedReferenceValues } from "./types.js";
1
+ import { type IResolvedReferenceValues, type ITooltipLocalizedStrings } from "./types.js";
2
2
  /**
3
3
  * Merge order matters: in-chart values override external ones, because the
4
4
  * in-chart value is what the user already sees on the rendered point/feature.
@@ -7,4 +7,4 @@ import { type IResolvedReferenceValues } from "./types.js";
7
7
  *
8
8
  * @internal
9
9
  */
10
- export declare function composeCustomTooltipSectionHtml(content: string, inChartValues: IResolvedReferenceValues, externalValues: IResolvedReferenceValues, fallbackText: string): string;
10
+ export declare function composeCustomTooltipSectionHtml(content: string, inChartValues: IResolvedReferenceValues, externalValues: IResolvedReferenceValues, localizedStrings: ITooltipLocalizedStrings): string;
@@ -9,8 +9,8 @@ import { resolveReferences } from "./referenceResolver.js";
9
9
  *
10
10
  * @internal
11
11
  */
12
- export function composeCustomTooltipSectionHtml(content, inChartValues, externalValues, fallbackText) {
12
+ export function composeCustomTooltipSectionHtml(content, inChartValues, externalValues, localizedStrings) {
13
13
  const merged = { ...externalValues, ...inChartValues };
14
- const resolved = resolveReferences(content, merged, fallbackText);
14
+ const resolved = resolveReferences(content, merged, localizedStrings);
15
15
  return `<div class="gd-viz-tooltip-custom-section">${markdownToHtml(resolved)}</div>`;
16
16
  }
@@ -0,0 +1,11 @@
1
+ import { type IntlShape } from "react-intl";
2
+ import { type ITooltipLocalizedStrings } from "./types.js";
3
+ /**
4
+ * Builds the localized placeholder strings for the non-value reference states,
5
+ * shared by every tooltip consumer (Highcharts, geo) so the wording and the
6
+ * message ids live in one place. `intl` is optional — the Highcharts tooltip
7
+ * formatter receives it optionally — and falls back to English.
8
+ *
9
+ * @internal
10
+ */
11
+ export declare function buildTooltipLocalizedStrings(intl?: IntlShape): ITooltipLocalizedStrings;
@@ -0,0 +1,22 @@
1
+ // (C) 2026 GoodData Corporation
2
+ import { defineMessages } from "react-intl";
3
+ const messages = defineMessages({
4
+ noFetch: { id: "richText.no_fetch" },
5
+ noData: { id: "richText.no_data" },
6
+ multipleItems: { id: "richText.multiple_data" },
7
+ });
8
+ /**
9
+ * Builds the localized placeholder strings for the non-value reference states,
10
+ * shared by every tooltip consumer (Highcharts, geo) so the wording and the
11
+ * message ids live in one place. `intl` is optional — the Highcharts tooltip
12
+ * formatter receives it optionally — and falls back to English.
13
+ *
14
+ * @internal
15
+ */
16
+ export function buildTooltipLocalizedStrings(intl) {
17
+ return {
18
+ noFetch: intl ? `(${intl.formatMessage(messages.noFetch)})` : "(Data could not be retrieved)",
19
+ noData: intl ? `(${intl.formatMessage(messages.noData)})` : "(No data)",
20
+ multipleItems: intl ? `(${intl.formatMessage(messages.multipleItems)})` : "(Multiple items)",
21
+ };
22
+ }
@@ -1,4 +1,4 @@
1
- import { type IResolvedReferenceValues } from "./types.js";
1
+ import { type IResolvedReferenceValues, type ITooltipLocalizedStrings } from "./types.js";
2
2
  /**
3
3
  * Substitutes `{metric/id}` and `{label/id}` references in markdown content
4
4
  * with resolved values from the lookup table.
@@ -9,11 +9,11 @@ import { type IResolvedReferenceValues } from "./types.js";
9
9
  * unintended formatting. `markdownToHtml` understands the backslash escapes.
10
10
  *
11
11
  * @param content - Markdown content with reference placeholders
12
- * @param values - Lookup of `metric/id` and `label/id` keys to formatted values.
12
+ * @param values - Lookup of `metric/id` and `label/id` keys to resolved statuses.
13
13
  * Keys must use a lowercase prefix; LDM identifiers are case-sensitive.
14
- * @param fallbackText - Localized text shown when a reference is recognized
15
- * but no value is available (unknown identifier, point with no value, etc.).
14
+ * @param strings - Localized placeholders for the non-value states (no data,
15
+ * multiple items, could-not-retrieve).
16
16
  *
17
17
  * @internal
18
18
  */
19
- export declare function resolveReferences(content: string, values: IResolvedReferenceValues, fallbackText: string): string;
19
+ export declare function resolveReferences(content: string, values: IResolvedReferenceValues, strings: ITooltipLocalizedStrings): string;
@@ -9,6 +9,24 @@ const MARKDOWN_METACHARS = /[\\*_`\[\]()!#~+\-]/g;
9
9
  function escapeMarkdownMetachars(value) {
10
10
  return value.replace(MARKDOWN_METACHARS, "\\$&");
11
11
  }
12
+ /**
13
+ * Renders a single resolved reference status to its display string. A reference
14
+ * with no status at this point (e.g. an in-chart sibling not present on the
15
+ * hovered series) is surfaced as unretrievable rather than masked as "no data".
16
+ */
17
+ function renderReference(ref, strings) {
18
+ switch (ref?.kind) {
19
+ case "value":
20
+ return ref.text;
21
+ case "empty":
22
+ return strings.noData;
23
+ case "multiple":
24
+ return strings.multipleItems;
25
+ case "error":
26
+ default:
27
+ return strings.noFetch;
28
+ }
29
+ }
12
30
  /**
13
31
  * Substitutes `{metric/id}` and `{label/id}` references in markdown content
14
32
  * with resolved values from the lookup table.
@@ -19,14 +37,14 @@ function escapeMarkdownMetachars(value) {
19
37
  * unintended formatting. `markdownToHtml` understands the backslash escapes.
20
38
  *
21
39
  * @param content - Markdown content with reference placeholders
22
- * @param values - Lookup of `metric/id` and `label/id` keys to formatted values.
40
+ * @param values - Lookup of `metric/id` and `label/id` keys to resolved statuses.
23
41
  * Keys must use a lowercase prefix; LDM identifiers are case-sensitive.
24
- * @param fallbackText - Localized text shown when a reference is recognized
25
- * but no value is available (unknown identifier, point with no value, etc.).
42
+ * @param strings - Localized placeholders for the non-value states (no data,
43
+ * multiple items, could-not-retrieve).
26
44
  *
27
45
  * @internal
28
46
  */
29
- export function resolveReferences(content, values, fallbackText) {
47
+ export function resolveReferences(content, values, strings) {
30
48
  if (!content) {
31
49
  return "";
32
50
  }
@@ -34,7 +52,7 @@ export function resolveReferences(content, values, fallbackText) {
34
52
  // The regex matches the prefix case-insensitively; storage uses
35
53
  // lowercase prefixes so users can write either `{metric/foo}` or
36
54
  // `{Metric/foo}`. LDM identifiers stay as-is — they are case-sensitive.
37
- const value = values[`${prefix.toLowerCase()}/${identifier}`];
38
- return escapeMarkdownMetachars(value === undefined ? fallbackText : value);
55
+ const ref = values[`${prefix.toLowerCase()}/${identifier}`];
56
+ return escapeMarkdownMetachars(renderReference(ref, strings));
39
57
  });
40
58
  }
@@ -0,0 +1,22 @@
1
+ import { type ISeparators } from "@gooddata/sdk-model";
2
+ import { type ResolvedReference } from "./types.js";
3
+ /**
4
+ * Maps a raw measure value to a {@link ResolvedReference} status: `null`/
5
+ * `undefined` → empty ("No data"); otherwise the formatted (or stringified)
6
+ * value. Shared by every tooltip resolver so the value→status mapping has a
7
+ * single home. Callers whose source can yield non-numeric / non-finite values
8
+ * (e.g. geo feature payloads) normalize those to `null` before calling.
9
+ *
10
+ * @internal
11
+ */
12
+ export declare function measureReference(rawValue: number | string | null | undefined, format: string | undefined, separators?: ISeparators): ResolvedReference;
13
+ /**
14
+ * Maps a label/attribute display value to a {@link ResolvedReference} status:
15
+ * `null` / `undefined` / empty string → empty ("No data"); otherwise the value.
16
+ * Shared by every tooltip resolver so empty-value handling can't drift between
17
+ * the in-chart and external paths. The count-based "multiple" case stays with
18
+ * the caller (only the lookup builder knows the per-row count).
19
+ *
20
+ * @internal
21
+ */
22
+ export declare function labelReference(value: string | number | null | undefined): ResolvedReference;
@@ -0,0 +1,33 @@
1
+ // (C) 2026 GoodData Corporation
2
+ import { ClientFormatterFacade } from "@gooddata/number-formatter";
3
+ /**
4
+ * Maps a raw measure value to a {@link ResolvedReference} status: `null`/
5
+ * `undefined` → empty ("No data"); otherwise the formatted (or stringified)
6
+ * value. Shared by every tooltip resolver so the value→status mapping has a
7
+ * single home. Callers whose source can yield non-numeric / non-finite values
8
+ * (e.g. geo feature payloads) normalize those to `null` before calling.
9
+ *
10
+ * @internal
11
+ */
12
+ export function measureReference(rawValue, format, separators) {
13
+ if (rawValue == null) {
14
+ return { kind: "empty" };
15
+ }
16
+ if (format) {
17
+ const { formattedValue } = ClientFormatterFacade.formatValue(Number(rawValue), format, separators);
18
+ return { kind: "value", text: formattedValue };
19
+ }
20
+ return { kind: "value", text: String(rawValue) };
21
+ }
22
+ /**
23
+ * Maps a label/attribute display value to a {@link ResolvedReference} status:
24
+ * `null` / `undefined` / empty string → empty ("No data"); otherwise the value.
25
+ * Shared by every tooltip resolver so empty-value handling can't drift between
26
+ * the in-chart and external paths. The count-based "multiple" case stays with
27
+ * the caller (only the lookup builder knows the per-row count).
28
+ *
29
+ * @internal
30
+ */
31
+ export function labelReference(value) {
32
+ return value == null || value === "" ? { kind: "empty" } : { kind: "value", text: String(value) };
33
+ }
@@ -23,6 +23,20 @@ export interface ITooltipExecutionBundle {
23
23
  execution: IPreparedExecution;
24
24
  meta: ITooltipExecutionMeta;
25
25
  }
26
+ /**
27
+ * A tooltip execution plan: one batched execution for all external references,
28
+ * plus per-reference bundles used as an isolation fallback. When the batch
29
+ * rejects (e.g. a single invalid reference 400s the whole AFM), the consumer
30
+ * re-runs the per-reference bundles so one bad reference can't suppress the
31
+ * rest. `perRef` is a thunk: the bundles are built lazily, only when the batch
32
+ * fails, so consumers that never fan out (e.g. geo) pay nothing for it.
33
+ *
34
+ * @internal
35
+ */
36
+ export interface ITooltipExecution {
37
+ batch: ITooltipExecutionBundle;
38
+ perRef: () => readonly ITooltipExecutionBundle[];
39
+ }
26
40
  /**
27
41
  * @internal
28
42
  */
@@ -37,7 +51,9 @@ export interface IBuildTooltipExecutionOptions {
37
51
  /**
38
52
  * Returns `null` when the content has no references or all references are
39
53
  * already in the chart (resolvable from drill data without a secondary call).
54
+ * Otherwise returns the batched execution plus per-reference bundles for the
55
+ * fan-out fallback (see {@link ITooltipExecution}).
40
56
  *
41
57
  * @internal
42
58
  */
43
- export declare function buildTooltipExecution(executionFactory: IExecutionFactory, chartDefinition: IExecutionDefinition, tooltipContent: string, options?: IBuildTooltipExecutionOptions): ITooltipExecutionBundle | null;
59
+ export declare function buildTooltipExecution(executionFactory: IExecutionFactory, chartDefinition: IExecutionDefinition, tooltipContent: string, options?: IBuildTooltipExecutionOptions): ITooltipExecution | null;
@@ -67,26 +67,27 @@ function getFilterDependencyMeasures(filters, chartMeasures) {
67
67
  return chartMeasures.filter((m) => neededLocalIds.has(measureLocalId(m)));
68
68
  }
69
69
  /**
70
- * Build tooltip-only measures for refs not already in the chart.
71
- * Labels get a max+count pair (mirrors the RichText widget pattern) so the
72
- * lookup can render "(Multiple items)" when a label resolves to >1 value per row.
70
+ * Build tooltip-only measures for the given references (already filtered to
71
+ * those not in the chart). Labels get a max+count pair (mirrors the RichText
72
+ * widget pattern) so the lookup can render "(Multiple items)" when a label
73
+ * resolves to >1 value per row.
73
74
  *
74
75
  * LocalId prefixes `tt_m_`, `tt_lv_`, `tt_lc_` are reserved — collision with
75
76
  * chart-side measure localIds would break filter-dependency reuse.
76
77
  */
77
- function buildTooltipItems(refs, chartMetricIds, chartLabelIds) {
78
+ function buildTooltipItems(refs) {
78
79
  const measures = [];
79
80
  const labelCountMap = {};
80
81
  const labelIdMap = {};
81
82
  const measureIdMap = {};
82
83
  let idx = 0;
83
84
  for (const ref of refs) {
84
- if (ref.type === "metric" && !chartMetricIds.has(ref.id)) {
85
+ if (ref.type === "metric") {
85
86
  const localId = `tt_m_${idx++}`;
86
87
  measures.push(newMeasure(idRef(ref.id, "measure"), (m) => m.localId(localId)));
87
88
  measureIdMap[localId] = ref.id;
88
89
  }
89
- else if (ref.type === "label" && !chartLabelIds.has(ref.id)) {
90
+ else {
90
91
  const valueLocalId = `tt_lv_${idx}`;
91
92
  const countLocalId = `tt_lc_${idx}`;
92
93
  idx++;
@@ -119,19 +120,12 @@ function getSlicingAttributes(definition, slicingAttributeLocalIds) {
119
120
  return out;
120
121
  }
121
122
  /**
122
- * Returns `null` when the content has no references or all references are
123
- * already in the chart (resolvable from drill data without a secondary call).
124
- *
125
- * @internal
123
+ * Builds a single execution bundle for the given external references (slicing
124
+ * attributes + tooltip measures + filter-dependency measures). Returns `null`
125
+ * when there are no measures to fetch.
126
126
  */
127
- export function buildTooltipExecution(executionFactory, chartDefinition, tooltipContent, options) {
128
- const refs = parseReferences(tooltipContent);
129
- if (refs.length === 0) {
130
- return null;
131
- }
132
- const chartMetricIds = getChartMetricIds(chartDefinition);
133
- const chartLabelIds = getChartLabelIds(chartDefinition);
134
- const { measures, labelCountMap, labelIdMap, measureIdMap } = buildTooltipItems(refs, chartMetricIds, chartLabelIds);
127
+ function buildBundle(executionFactory, chartDefinition, externalRefs, options) {
128
+ const { measures, labelCountMap, labelIdMap, measureIdMap } = buildTooltipItems(externalRefs);
135
129
  if (measures.length === 0) {
136
130
  return null;
137
131
  }
@@ -150,3 +144,31 @@ export function buildTooltipExecution(executionFactory, chartDefinition, tooltip
150
144
  meta: { labelCountMap, measureIdMap, labelIdMap },
151
145
  };
152
146
  }
147
+ /**
148
+ * Returns `null` when the content has no references or all references are
149
+ * already in the chart (resolvable from drill data without a secondary call).
150
+ * Otherwise returns the batched execution plus per-reference bundles for the
151
+ * fan-out fallback (see {@link ITooltipExecution}).
152
+ *
153
+ * @internal
154
+ */
155
+ export function buildTooltipExecution(executionFactory, chartDefinition, tooltipContent, options) {
156
+ const refs = parseReferences(tooltipContent);
157
+ if (refs.length === 0) {
158
+ return null;
159
+ }
160
+ const chartMetricIds = getChartMetricIds(chartDefinition);
161
+ const chartLabelIds = getChartLabelIds(chartDefinition);
162
+ // References not already resolvable from the chart's own drill data.
163
+ const externalRefs = refs.filter((ref) => (ref.type === "metric" && !chartMetricIds.has(ref.id)) ||
164
+ (ref.type === "label" && !chartLabelIds.has(ref.id)));
165
+ const batch = buildBundle(executionFactory, chartDefinition, externalRefs, options);
166
+ if (!batch) {
167
+ return null;
168
+ }
169
+ // Lazy: built only on batch failure (the Highcharts fan-out); geo never calls it.
170
+ const perRef = () => externalRefs
171
+ .map((ref) => buildBundle(executionFactory, chartDefinition, [ref], options))
172
+ .filter((bundle) => bundle !== null);
173
+ return { batch, perRef };
174
+ }
@@ -2,20 +2,12 @@ import { type IDataView } from "@gooddata/sdk-backend-spi";
2
2
  import { type ISeparators } from "@gooddata/sdk-model";
3
3
  import { type ITooltipExecutionMeta } from "./tooltipExecution.js";
4
4
  import { type IResolvedReferenceValues } from "./types.js";
5
- /**
6
- * Localized placeholders for unresolved reference values. Mirrors the RichText
7
- * widget's `richText.no_data` / `richText.multiple_data` messages.
8
- *
9
- * @internal
10
- */
11
- export interface ITooltipLookupLocalizedStrings {
12
- noData: string;
13
- multipleItems: string;
14
- }
15
5
  /**
16
6
  * Build a per-data-point lookup keyed by `${displayFormId}:${uri}` segments
17
7
  * (joined by `|`, sorted). Iteration is orientation-agnostic via slices/series.
8
+ * Each reference is tagged with a {@link ResolvedReference} status; localized
9
+ * placeholder strings are applied later, at the render site.
18
10
  *
19
11
  * @internal
20
12
  */
21
- export declare function buildLookupTable(dataView: IDataView, meta: ITooltipExecutionMeta, separators?: ISeparators, localizedStrings?: ITooltipLookupLocalizedStrings): Map<string, IResolvedReferenceValues>;
13
+ export declare function buildLookupTable(dataView: IDataView, meta: ITooltipExecutionMeta, separators?: ISeparators): Map<string, IResolvedReferenceValues>;
@@ -1,19 +1,18 @@
1
1
  // (C) 2026 GoodData Corporation
2
- import { ClientFormatterFacade } from "@gooddata/number-formatter";
3
2
  import { isResultAttributeHeader } from "@gooddata/sdk-model";
4
3
  import { DataViewFacade } from "@gooddata/sdk-ui";
4
+ import { labelReference, measureReference } from "./referenceStatus.js";
5
5
  import { buildKeySegment, joinKeySegments } from "./tooltipKey.js";
6
- const DEFAULT_LOCALIZED_STRINGS = {
7
- noData: "(No data)",
8
- multipleItems: "(Multiple items)",
9
- };
6
+ import { labelKey, metricKey } from "./types.js";
10
7
  /**
11
8
  * Build a per-data-point lookup keyed by `${displayFormId}:${uri}` segments
12
9
  * (joined by `|`, sorted). Iteration is orientation-agnostic via slices/series.
10
+ * Each reference is tagged with a {@link ResolvedReference} status; localized
11
+ * placeholder strings are applied later, at the render site.
13
12
  *
14
13
  * @internal
15
14
  */
16
- export function buildLookupTable(dataView, meta, separators, localizedStrings = DEFAULT_LOCALIZED_STRINGS) {
15
+ export function buildLookupTable(dataView, meta, separators) {
17
16
  const lookup = new Map();
18
17
  const facade = DataViewFacade.for(dataView);
19
18
  const slices = facade.data().slices().toArray();
@@ -51,30 +50,14 @@ export function buildLookupTable(dataView, meta, separators, localizedStrings =
51
50
  const countValue = countSeries
52
51
  ? Number(countSeries.dataPoints()[sliceIdx]?.rawValue ?? 0)
53
52
  : 1;
54
- if (countValue > 1) {
55
- values[`label/${labelId}`] = localizedStrings.multipleItems;
56
- }
57
- else if (rawValue == null || rawValue === "") {
58
- values[`label/${labelId}`] = localizedStrings.noData;
59
- }
60
- else {
61
- values[`label/${labelId}`] = String(rawValue);
62
- }
53
+ // count > 1 → "(Multiple items)"; else empty/value via the shared helper.
54
+ values[labelKey(labelId)] = countValue > 1 ? { kind: "multiple" } : labelReference(rawValue);
63
55
  continue;
64
56
  }
65
57
  const metricId = meta.measureIdMap[localId];
66
58
  if (metricId) {
67
59
  const format = measureDesc.measureHeaderItem.format;
68
- if (rawValue == null) {
69
- values[`metric/${metricId}`] = localizedStrings.noData;
70
- }
71
- else if (format) {
72
- const { formattedValue } = ClientFormatterFacade.formatValue(Number(rawValue), format, separators);
73
- values[`metric/${metricId}`] = formattedValue;
74
- }
75
- else {
76
- values[`metric/${metricId}`] = String(rawValue);
77
- }
60
+ values[metricKey(metricId)] = measureReference(rawValue, format, separators);
78
61
  }
79
62
  }
80
63
  lookup.set(pointKey, values);
@@ -59,10 +59,58 @@ export interface ICustomTooltipConfig {
59
59
  placement?: CustomTooltipPlacement;
60
60
  }
61
61
  /**
62
- * Lookup of resolved reference values keyed by `metric/id` or `label/id`.
62
+ * Resolution outcome for a single `{metric/id}` / `{label/id}` reference at a
63
+ * data point. A discriminated union so the renderer maps each state to its own
64
+ * localized message instead of collapsing every "missing" case into one
65
+ * fallback: `empty` → "(No data)", `multiple` → "(Multiple items)", `error` →
66
+ * "(Data could not be retrieved)". `error` is emitted only when a value was
67
+ * genuinely unretrievable (e.g. a reference whose fetch failed); it is never a
68
+ * default for an unclassified value.
69
+ *
70
+ * @internal
71
+ */
72
+ export type ResolvedReference = {
73
+ readonly kind: "value";
74
+ readonly text: string;
75
+ } | {
76
+ readonly kind: "empty";
77
+ } | {
78
+ readonly kind: "multiple";
79
+ } | {
80
+ readonly kind: "error";
81
+ };
82
+ /**
83
+ * Lookup of resolved reference statuses keyed by `metric/id` or `label/id`.
63
84
  *
64
85
  * @internal
65
86
  */
66
87
  export interface IResolvedReferenceValues {
67
- [referenceKey: string]: string | undefined;
88
+ [referenceKey: string]: ResolvedReference | undefined;
89
+ }
90
+ /**
91
+ * Builds the `metric/<id>` lookup key for a metric reference. A reference key
92
+ * has exactly two shapes ({@link metricKey}, {@link labelKey}); keeping the
93
+ * convention here is the single source for every write site. The read side
94
+ * parses references via `REFERENCE_REGEX_MATCH` in `resolveReferences`.
95
+ *
96
+ * @internal
97
+ */
98
+ export declare const metricKey: (id: string) => string;
99
+ /**
100
+ * Builds the `label/<id>` lookup key for a label reference. See {@link metricKey}.
101
+ *
102
+ * @internal
103
+ */
104
+ export declare const labelKey: (id: string) => string;
105
+ /**
106
+ * Localized placeholder strings for the non-value reference states. Built once
107
+ * at the render site (where `intl` is available) and threaded into
108
+ * `resolveReferences`, so reference resolution stays free of i18n concerns.
109
+ *
110
+ * @internal
111
+ */
112
+ export interface ITooltipLocalizedStrings {
113
+ readonly noData: string;
114
+ readonly multipleItems: string;
115
+ readonly noFetch: string;
68
116
  }
@@ -1,2 +1,16 @@
1
1
  // (C) 2026 GoodData Corporation
2
- export {};
2
+ /**
3
+ * Builds the `metric/<id>` lookup key for a metric reference. A reference key
4
+ * has exactly two shapes ({@link metricKey}, {@link labelKey}); keeping the
5
+ * convention here is the single source for every write site. The read side
6
+ * parses references via `REFERENCE_REGEX_MATCH` in `resolveReferences`.
7
+ *
8
+ * @internal
9
+ */
10
+ export const metricKey = (id) => `metric/${id}`;
11
+ /**
12
+ * Builds the `label/<id>` lookup key for a label reference. See {@link metricKey}.
13
+ *
14
+ * @internal
15
+ */
16
+ export const labelKey = (id) => `label/${id}`;
@@ -1,8 +1,27 @@
1
1
  import { type IPreparedExecution } from "@gooddata/sdk-backend-spi";
2
2
  import { type ISeparators } from "@gooddata/sdk-model";
3
- import { type ITooltipExecutionBundle, type ITooltipExecutionMeta } from "./tooltipExecution.js";
4
- import { type ITooltipLookupLocalizedStrings } from "./tooltipLookup.js";
3
+ import { type ITooltipExecution, type ITooltipExecutionMeta } from "./tooltipExecution.js";
5
4
  import { type IResolvedReferenceValues } from "./types.js";
5
+ /**
6
+ * Built lookup plus references that could not be retrieved at all (their fetch
7
+ * rejected even in the per-reference fallback). Errored references render as
8
+ * "(Data could not be retrieved)" at every point.
9
+ *
10
+ * @internal
11
+ */
12
+ export interface ITooltipLookupResult {
13
+ lookup: Map<string, IResolvedReferenceValues>;
14
+ erroredRefs: ReadonlySet<string>;
15
+ }
16
+ /**
17
+ * Single-execution variant for chart families that have one tooltip execution
18
+ * per chart (e.g. Highcharts). Returns `undefined` while no execution is
19
+ * provided or before the first result lands; consumers handle that as "no
20
+ * external values".
21
+ *
22
+ * @internal
23
+ */
24
+ export declare function useTooltipLookup(execution: ITooltipExecution | undefined, separators?: ISeparators): ITooltipLookupResult | undefined;
6
25
  /**
7
26
  * One prepared tooltip execution paired with a caller-owned key and the
8
27
  * context that travels with the built lookup.
@@ -25,19 +44,11 @@ export interface ITooltipLookupExecutionResult<TContext> {
25
44
  context: TContext;
26
45
  }
27
46
  /**
28
- * Single-bundle variant for chart families that have one tooltip execution per
29
- * chart (e.g. Highcharts). Returns `undefined` while no bundle is provided or
30
- * before the first result lands; consumers handle that as "no external values".
31
- *
32
- * @internal
33
- */
34
- export declare function useTooltipLookup(bundle: ITooltipExecutionBundle | undefined, separators?: ISeparators, localizedStrings?: ITooltipLookupLocalizedStrings): Map<string, IResolvedReferenceValues> | undefined;
35
- /**
36
- * Multi-bundle variant for chart families that key tooltip executions per
47
+ * Multi-execution variant for chart families that key tooltip executions per
37
48
  * sub-target (e.g. geo per-layer). `context` is required so the produced
38
49
  * lookup carries whatever the caller needs to interpret the result —
39
50
  * downstream code does not have to defensively check for missing context.
40
51
  *
41
52
  * @internal
42
53
  */
43
- export declare function useTooltipLookupExecutions<TContext>(entries: readonly ITooltipLookupExecutionEntry<TContext>[], separators?: ISeparators, localizedStrings?: ITooltipLookupLocalizedStrings): Map<string, ITooltipLookupExecutionResult<TContext>>;
54
+ export declare function useTooltipLookupExecutions<TContext>(entries: readonly ITooltipLookupExecutionEntry<TContext>[], separators?: ISeparators): Map<string, ITooltipLookupExecutionResult<TContext>>;
@@ -2,47 +2,97 @@
2
2
  import { useMemo } from "react";
3
3
  import { useCancelablePromise } from "@gooddata/sdk-ui";
4
4
  import { buildLookupTable } from "./tooltipLookup.js";
5
- const EMPTY_LOOKUPS = new Map();
5
+ import { labelKey, metricKey } from "./types.js";
6
6
  async function executeOne(execution) {
7
7
  const result = await execution.execute();
8
8
  return result.readAll();
9
9
  }
10
- function getEntriesFingerprint(entries) {
11
- return entries.map((entry) => `${entry.key}::${entry.execution.fingerprint()}`).join("||");
10
+ /**
11
+ * Reference keys (`metric/id`, `label/id`) a bundle's meta covers. Used to mark
12
+ * a failed per-reference bundle's references as errored.
13
+ */
14
+ function refKeysOfMeta(meta) {
15
+ return [
16
+ ...Object.values(meta.measureIdMap).map(metricKey),
17
+ ...Object.values(meta.labelIdMap).map(labelKey),
18
+ ];
12
19
  }
13
- async function executeAll(entries) {
14
- const settled = await Promise.allSettled(entries.map(async (entry) => ({ ...entry, dataView: await executeOne(entry.execution) })));
15
- // Failed entries drop out silently; callers fall back when a lookup is missing.
16
- return settled.flatMap((result) => (result.status === "fulfilled" ? [result.value] : []));
20
+ /**
21
+ * Execute the batch; on failure, fan out to per-reference bundles so a single
22
+ * bad reference (e.g. one that 400s the batched AFM) only errors itself while
23
+ * the rest still resolve. No reliance on parsing the backend error — failure is
24
+ * isolated structurally by which per-reference execution rejects.
25
+ */
26
+ async function runWithFallback(execution) {
27
+ try {
28
+ const dataView = await executeOne(execution.batch.execution);
29
+ return { inputs: [{ dataView, meta: execution.batch.meta }], erroredRefs: new Set() };
30
+ }
31
+ catch {
32
+ // Build the per-reference bundles now (lazy) and isolate each.
33
+ const perRef = execution.perRef();
34
+ const settled = await Promise.allSettled(perRef.map((bundle) => executeOne(bundle.execution)));
35
+ const inputs = [];
36
+ const erroredRefs = new Set();
37
+ settled.forEach((result, index) => {
38
+ const bundle = perRef[index];
39
+ if (result.status === "fulfilled") {
40
+ inputs.push({ dataView: result.value, meta: bundle.meta });
41
+ }
42
+ else {
43
+ refKeysOfMeta(bundle.meta).forEach((key) => erroredRefs.add(key));
44
+ }
45
+ });
46
+ return { inputs, erroredRefs };
47
+ }
48
+ }
49
+ /**
50
+ * Merge per-execution lookups into one map (by point key, shallow-merging the
51
+ * per-point reference statuses) and pair it with the errored references.
52
+ */
53
+ function buildResult(outcome, separators) {
54
+ const lookup = new Map();
55
+ for (const { dataView, meta } of outcome.inputs) {
56
+ for (const [pointKey, values] of buildLookupTable(dataView, meta, separators)) {
57
+ const existing = lookup.get(pointKey);
58
+ lookup.set(pointKey, existing ? { ...existing, ...values } : values);
59
+ }
60
+ }
61
+ return { lookup, erroredRefs: outcome.erroredRefs };
17
62
  }
18
63
  /**
19
- * Single-bundle variant for chart families that have one tooltip execution per
20
- * chart (e.g. Highcharts). Returns `undefined` while no bundle is provided or
21
- * before the first result lands; consumers handle that as "no external values".
64
+ * Single-execution variant for chart families that have one tooltip execution
65
+ * per chart (e.g. Highcharts). Returns `undefined` while no execution is
66
+ * provided or before the first result lands; consumers handle that as "no
67
+ * external values".
22
68
  *
23
69
  * @internal
24
70
  */
25
- export function useTooltipLookup(bundle, separators, localizedStrings) {
26
- const fingerprint = bundle?.execution.fingerprint();
71
+ export function useTooltipLookup(execution, separators) {
72
+ const fingerprint = execution?.batch.execution.fingerprint();
27
73
  const { result } = useCancelablePromise({
28
- promise: bundle ? () => executeOne(bundle.execution) : undefined,
74
+ promise: execution ? () => runWithFallback(execution) : undefined,
29
75
  }, [fingerprint]);
30
- return useMemo(() => {
31
- if (!result || !bundle) {
32
- return undefined;
33
- }
34
- return buildLookupTable(result, bundle.meta, separators, localizedStrings);
35
- }, [result, bundle, separators, localizedStrings]);
76
+ return useMemo(() => (result ? buildResult(result, separators) : undefined), [result, separators]);
77
+ }
78
+ const EMPTY_LOOKUPS = new Map();
79
+ function getEntriesFingerprint(entries) {
80
+ return entries.map((entry) => `${entry.key}::${entry.execution.fingerprint()}`).join("||");
81
+ }
82
+ async function executeAll(entries) {
83
+ const settled = await Promise.allSettled(entries.map(async (entry) => ({ ...entry, dataView: await executeOne(entry.execution) })));
84
+ // Failed entries drop out silently; callers fall back when a lookup is missing.
85
+ return settled.flatMap((result) => (result.status === "fulfilled" ? [result.value] : []));
36
86
  }
37
87
  /**
38
- * Multi-bundle variant for chart families that key tooltip executions per
88
+ * Multi-execution variant for chart families that key tooltip executions per
39
89
  * sub-target (e.g. geo per-layer). `context` is required so the produced
40
90
  * lookup carries whatever the caller needs to interpret the result —
41
91
  * downstream code does not have to defensively check for missing context.
42
92
  *
43
93
  * @internal
44
94
  */
45
- export function useTooltipLookupExecutions(entries, separators, localizedStrings) {
95
+ export function useTooltipLookupExecutions(entries, separators) {
46
96
  const fingerprint = getEntriesFingerprint(entries);
47
97
  const { result } = useCancelablePromise({
48
98
  promise: entries.length > 0 ? () => executeAll(entries) : undefined,
@@ -54,10 +104,10 @@ export function useTooltipLookupExecutions(entries, separators, localizedStrings
54
104
  const lookups = new Map();
55
105
  for (const entry of result) {
56
106
  lookups.set(entry.key, {
57
- lookup: buildLookupTable(entry.dataView, entry.meta, separators, localizedStrings),
107
+ lookup: buildLookupTable(entry.dataView, entry.meta, separators),
58
108
  context: entry.context,
59
109
  });
60
110
  }
61
111
  return lookups;
62
- }, [result, separators, localizedStrings]);
112
+ }, [result, separators]);
63
113
  }
package/esm/index.d.ts CHANGED
@@ -28,12 +28,14 @@ export { getHeadlineResponsiveClassName } from "./utils/headlineResponsiveClassN
28
28
  export { getLegendDetails, type ILegendDetails, type ILegendDetailOptions, } from "./legend/PopUpLegend/helpers.js";
29
29
  export { PATTERN_FILLS, getPatternFillByIndex, getPatternFillByName, getPatternFill, type IPatternFill, type PatternFillName, type IChartFillConfig, } from "./coloring/patternFills.js";
30
30
  export { PatternFill, type IPatternFillProps } from "./coloring/PatternFill.js";
31
- export { type ICustomTooltipConfig, type CustomTooltipPlacement, type IResolvedReferenceValues, } from "./customTooltip/types.js";
31
+ export { type ICustomTooltipConfig, type CustomTooltipPlacement, type IResolvedReferenceValues, type ResolvedReference, type ITooltipLocalizedStrings, metricKey, labelKey, } from "./customTooltip/types.js";
32
32
  export { markdownToHtml } from "./customTooltip/markdownToHtml.js";
33
33
  export { resolveReferences } from "./customTooltip/referenceResolver.js";
34
+ export { measureReference, labelReference } from "./customTooltip/referenceStatus.js";
35
+ export { buildTooltipLocalizedStrings } from "./customTooltip/localizedStrings.js";
34
36
  export { resolveMeasureLdmIdentifier } from "./customTooltip/measureLdmIdentifier.js";
35
- export { buildTooltipExecution, type IBuildTooltipExecutionOptions, type ITooltipExecutionBundle, type ITooltipExecutionMeta, } from "./customTooltip/tooltipExecution.js";
36
- export { buildLookupTable, type ITooltipLookupLocalizedStrings } from "./customTooltip/tooltipLookup.js";
37
+ export { buildTooltipExecution, type IBuildTooltipExecutionOptions, type ITooltipExecution, type ITooltipExecutionBundle, type ITooltipExecutionMeta, } from "./customTooltip/tooltipExecution.js";
38
+ export { buildLookupTable } from "./customTooltip/tooltipLookup.js";
37
39
  export { buildKeySegment, joinKeySegments } from "./customTooltip/tooltipKey.js";
38
40
  export { composeCustomTooltipSectionHtml } from "./customTooltip/composeSectionHtml.js";
39
- export { useTooltipLookup, useTooltipLookupExecutions, type ITooltipLookupExecutionEntry, type ITooltipLookupExecutionResult, } from "./customTooltip/useTooltipLookupExecutions.js";
41
+ export { useTooltipLookup, useTooltipLookupExecutions, type ITooltipLookupResult, type ITooltipLookupExecutionEntry, type ITooltipLookupExecutionResult, } from "./customTooltip/useTooltipLookupExecutions.js";
package/esm/index.js CHANGED
@@ -29,8 +29,11 @@ export { getHeadlineResponsiveClassName } from "./utils/headlineResponsiveClassN
29
29
  export { getLegendDetails, } from "./legend/PopUpLegend/helpers.js";
30
30
  export { PATTERN_FILLS, getPatternFillByIndex, getPatternFillByName, getPatternFill, } from "./coloring/patternFills.js";
31
31
  export { PatternFill } from "./coloring/PatternFill.js";
32
+ export { metricKey, labelKey, } from "./customTooltip/types.js";
32
33
  export { markdownToHtml } from "./customTooltip/markdownToHtml.js";
33
34
  export { resolveReferences } from "./customTooltip/referenceResolver.js";
35
+ export { measureReference, labelReference } from "./customTooltip/referenceStatus.js";
36
+ export { buildTooltipLocalizedStrings } from "./customTooltip/localizedStrings.js";
34
37
  export { resolveMeasureLdmIdentifier } from "./customTooltip/measureLdmIdentifier.js";
35
38
  export { buildTooltipExecution, } from "./customTooltip/tooltipExecution.js";
36
39
  export { buildLookupTable } from "./customTooltip/tooltipLookup.js";
@@ -21,6 +21,7 @@ import { IExecutionFactory } from '@gooddata/sdk-backend-spi';
21
21
  import { IHeaderPredicate } from '@gooddata/sdk-ui';
22
22
  import { IMappingHeader } from '@gooddata/sdk-ui';
23
23
  import { IMeasure } from '@gooddata/sdk-model';
24
+ import { IntlShape } from 'react-intl';
24
25
  import { IPreparedExecution } from '@gooddata/sdk-backend-spi';
25
26
  import { IRgbColorValue } from '@gooddata/sdk-model';
26
27
  import { ISeparators } from '@gooddata/sdk-model';
@@ -58,18 +59,32 @@ export declare function buildKeySegment(displayFormId: string, uri: string): str
58
59
  /**
59
60
  * Build a per-data-point lookup keyed by `${displayFormId}:${uri}` segments
60
61
  * (joined by `|`, sorted). Iteration is orientation-agnostic via slices/series.
62
+ * Each reference is tagged with a {@link ResolvedReference} status; localized
63
+ * placeholder strings are applied later, at the render site.
61
64
  *
62
65
  * @internal
63
66
  */
64
- export declare function buildLookupTable(dataView: IDataView, meta: ITooltipExecutionMeta, separators?: ISeparators, localizedStrings?: ITooltipLookupLocalizedStrings): Map<string, IResolvedReferenceValues>;
67
+ export declare function buildLookupTable(dataView: IDataView, meta: ITooltipExecutionMeta, separators?: ISeparators): Map<string, IResolvedReferenceValues>;
65
68
 
66
69
  /**
67
70
  * Returns `null` when the content has no references or all references are
68
71
  * already in the chart (resolvable from drill data without a secondary call).
72
+ * Otherwise returns the batched execution plus per-reference bundles for the
73
+ * fan-out fallback (see {@link ITooltipExecution}).
69
74
  *
70
75
  * @internal
71
76
  */
72
- export declare function buildTooltipExecution(executionFactory: IExecutionFactory, chartDefinition: IExecutionDefinition, tooltipContent: string, options?: IBuildTooltipExecutionOptions): ITooltipExecutionBundle | null;
77
+ export declare function buildTooltipExecution(executionFactory: IExecutionFactory, chartDefinition: IExecutionDefinition, tooltipContent: string, options?: IBuildTooltipExecutionOptions): ITooltipExecution | null;
78
+
79
+ /**
80
+ * Builds the localized placeholder strings for the non-value reference states,
81
+ * shared by every tooltip consumer (Highcharts, geo) so the wording and the
82
+ * message ids live in one place. `intl` is optional — the Highcharts tooltip
83
+ * formatter receives it optionally — and falls back to English.
84
+ *
85
+ * @internal
86
+ */
87
+ export declare function buildTooltipLocalizedStrings(intl?: IntlShape): ITooltipLocalizedStrings;
73
88
 
74
89
  /**
75
90
  * @internal
@@ -129,7 +144,7 @@ export declare const ColorUtils: {
129
144
  *
130
145
  * @internal
131
146
  */
132
- export declare function composeCustomTooltipSectionHtml(content: string, inChartValues: IResolvedReferenceValues, externalValues: IResolvedReferenceValues, fallbackText: string): string;
147
+ export declare function composeCustomTooltipSectionHtml(content: string, inChartValues: IResolvedReferenceValues, externalValues: IResolvedReferenceValues, localizedStrings: ITooltipLocalizedStrings): string;
133
148
 
134
149
  /**
135
150
  * Placement of the custom tooltip section relative to the default tooltip content.
@@ -679,12 +694,12 @@ export declare interface IRange {
679
694
  }
680
695
 
681
696
  /**
682
- * Lookup of resolved reference values keyed by `metric/id` or `label/id`.
697
+ * Lookup of resolved reference statuses keyed by `metric/id` or `label/id`.
683
698
  *
684
699
  * @internal
685
700
  */
686
701
  export declare interface IResolvedReferenceValues {
687
- [referenceKey: string]: string | undefined;
702
+ [referenceKey: string]: ResolvedReference | undefined;
688
703
  }
689
704
 
690
705
  /**
@@ -784,6 +799,21 @@ export declare function isValidMappedColor(colorItem: IColor | null | undefined,
784
799
  */
785
800
  export declare type ItemBorderRadiusPredicate = (item: any) => boolean;
786
801
 
802
+ /**
803
+ * A tooltip execution plan: one batched execution for all external references,
804
+ * plus per-reference bundles used as an isolation fallback. When the batch
805
+ * rejects (e.g. a single invalid reference 400s the whole AFM), the consumer
806
+ * re-runs the per-reference bundles so one bad reference can't suppress the
807
+ * rest. `perRef` is a thunk: the bundles are built lazily, only when the batch
808
+ * fails, so consumers that never fan out (e.g. geo) pay nothing for it.
809
+ *
810
+ * @internal
811
+ */
812
+ export declare interface ITooltipExecution {
813
+ batch: ITooltipExecutionBundle;
814
+ perRef: () => readonly ITooltipExecutionBundle[];
815
+ }
816
+
787
817
  /**
788
818
  * Prepared tooltip execution paired with the meta needed to interpret its result.
789
819
  * Carry them together — meta from one call mis-interprets results from another.
@@ -809,6 +839,19 @@ export declare interface ITooltipExecutionMeta {
809
839
  labelIdMap: Record<string, string>;
810
840
  }
811
841
 
842
+ /**
843
+ * Localized placeholder strings for the non-value reference states. Built once
844
+ * at the render site (where `intl` is available) and threaded into
845
+ * `resolveReferences`, so reference resolution stays free of i18n concerns.
846
+ *
847
+ * @internal
848
+ */
849
+ export declare interface ITooltipLocalizedStrings {
850
+ readonly noData: string;
851
+ readonly multipleItems: string;
852
+ readonly noFetch: string;
853
+ }
854
+
812
855
  /**
813
856
  * One prepared tooltip execution paired with a caller-owned key and the
814
857
  * context that travels with the built lookup.
@@ -833,14 +876,15 @@ export declare interface ITooltipLookupExecutionResult<TContext> {
833
876
  }
834
877
 
835
878
  /**
836
- * Localized placeholders for unresolved reference values. Mirrors the RichText
837
- * widget's `richText.no_data` / `richText.multiple_data` messages.
879
+ * Built lookup plus references that could not be retrieved at all (their fetch
880
+ * rejected even in the per-reference fallback). Errored references render as
881
+ * "(Data could not be retrieved)" at every point.
838
882
  *
839
883
  * @internal
840
884
  */
841
- export declare interface ITooltipLookupLocalizedStrings {
842
- noData: string;
843
- multipleItems: string;
885
+ export declare interface ITooltipLookupResult {
886
+ lookup: Map<string, IResolvedReferenceValues>;
887
+ erroredRefs: ReadonlySet<string>;
844
888
  }
845
889
 
846
890
  /**
@@ -848,6 +892,24 @@ export declare interface ITooltipLookupLocalizedStrings {
848
892
  */
849
893
  export declare function joinKeySegments(parts: readonly string[]): string;
850
894
 
895
+ /**
896
+ * Builds the `label/<id>` lookup key for a label reference. See {@link metricKey}.
897
+ *
898
+ * @internal
899
+ */
900
+ export declare const labelKey: (id: string) => string;
901
+
902
+ /**
903
+ * Maps a label/attribute display value to a {@link ResolvedReference} status:
904
+ * `null` / `undefined` / empty string → empty ("No data"); otherwise the value.
905
+ * Shared by every tooltip resolver so empty-value handling can't drift between
906
+ * the in-chart and external paths. The count-based "multiple" case stays with
907
+ * the caller (only the lookup builder knows the per-row count).
908
+ *
909
+ * @internal
910
+ */
911
+ export declare function labelReference(value: string | number | null | undefined): ResolvedReference;
912
+
851
913
  /**
852
914
  * @internal
853
915
  */
@@ -885,6 +947,27 @@ export declare const LegendPosition: {
885
947
  */
886
948
  export declare function markdownToHtml(markdown: string): string;
887
949
 
950
+ /**
951
+ * Maps a raw measure value to a {@link ResolvedReference} status: `null`/
952
+ * `undefined` → empty ("No data"); otherwise the formatted (or stringified)
953
+ * value. Shared by every tooltip resolver so the value→status mapping has a
954
+ * single home. Callers whose source can yield non-numeric / non-finite values
955
+ * (e.g. geo feature payloads) normalize those to `null` before calling.
956
+ *
957
+ * @internal
958
+ */
959
+ export declare function measureReference(rawValue: number | string | null | undefined, format: string | undefined, separators?: ISeparators): ResolvedReference;
960
+
961
+ /**
962
+ * Builds the `metric/<id>` lookup key for a metric reference. A reference key
963
+ * has exactly two shapes ({@link metricKey}, {@link labelKey}); keeping the
964
+ * convention here is the single source for every write site. The read side
965
+ * parses references via `REFERENCE_REGEX_MATCH` in `resolveReferences`.
966
+ *
967
+ * @internal
968
+ */
969
+ export declare const metricKey: (id: string) => string;
970
+
888
971
  /**
889
972
  * @internal
890
973
  */
@@ -947,6 +1030,28 @@ export declare function PopUpLegend({ name, maxRows, enableBorderRadius, series,
947
1030
  */
948
1031
  export declare type PositionType = "left" | "right" | "top" | "bottom" | "auto";
949
1032
 
1033
+ /**
1034
+ * Resolution outcome for a single `{metric/id}` / `{label/id}` reference at a
1035
+ * data point. A discriminated union so the renderer maps each state to its own
1036
+ * localized message instead of collapsing every "missing" case into one
1037
+ * fallback: `empty` → "(No data)", `multiple` → "(Multiple items)", `error` →
1038
+ * "(Data could not be retrieved)". `error` is emitted only when a value was
1039
+ * genuinely unretrievable (e.g. a reference whose fetch failed); it is never a
1040
+ * default for an unclassified value.
1041
+ *
1042
+ * @internal
1043
+ */
1044
+ export declare type ResolvedReference = {
1045
+ readonly kind: "value";
1046
+ readonly text: string;
1047
+ } | {
1048
+ readonly kind: "empty";
1049
+ } | {
1050
+ readonly kind: "multiple";
1051
+ } | {
1052
+ readonly kind: "error";
1053
+ };
1054
+
950
1055
  /**
951
1056
  * Returns the LDM identifier the measure ultimately resolves to.
952
1057
  *
@@ -968,14 +1073,14 @@ export declare function resolveMeasureLdmIdentifier(measure: IMeasure, allMeasur
968
1073
  * unintended formatting. `markdownToHtml` understands the backslash escapes.
969
1074
  *
970
1075
  * @param content - Markdown content with reference placeholders
971
- * @param values - Lookup of `metric/id` and `label/id` keys to formatted values.
1076
+ * @param values - Lookup of `metric/id` and `label/id` keys to resolved statuses.
972
1077
  * Keys must use a lowercase prefix; LDM identifiers are case-sensitive.
973
- * @param fallbackText - Localized text shown when a reference is recognized
974
- * but no value is available (unknown identifier, point with no value, etc.).
1078
+ * @param strings - Localized placeholders for the non-value states (no data,
1079
+ * multiple items, could-not-retrieve).
975
1080
  *
976
1081
  * @internal
977
1082
  */
978
- export declare function resolveReferences(content: string, values: IResolvedReferenceValues, fallbackText: string): string;
1083
+ export declare function resolveReferences(content: string, values: IResolvedReferenceValues, strings: ITooltipLocalizedStrings): string;
979
1084
 
980
1085
  /**
981
1086
  * @internal
@@ -999,23 +1104,24 @@ export declare const StaticLegend: NamedExoticComponent<IStaticLegendProps>;
999
1104
  export declare const SupportedLegendPositions: PositionType[];
1000
1105
 
1001
1106
  /**
1002
- * Single-bundle variant for chart families that have one tooltip execution per
1003
- * chart (e.g. Highcharts). Returns `undefined` while no bundle is provided or
1004
- * before the first result lands; consumers handle that as "no external values".
1107
+ * Single-execution variant for chart families that have one tooltip execution
1108
+ * per chart (e.g. Highcharts). Returns `undefined` while no execution is
1109
+ * provided or before the first result lands; consumers handle that as "no
1110
+ * external values".
1005
1111
  *
1006
1112
  * @internal
1007
1113
  */
1008
- export declare function useTooltipLookup(bundle: ITooltipExecutionBundle | undefined, separators?: ISeparators, localizedStrings?: ITooltipLookupLocalizedStrings): Map<string, IResolvedReferenceValues> | undefined;
1114
+ export declare function useTooltipLookup(execution: ITooltipExecution | undefined, separators?: ISeparators): ITooltipLookupResult | undefined;
1009
1115
 
1010
1116
  /**
1011
- * Multi-bundle variant for chart families that key tooltip executions per
1117
+ * Multi-execution variant for chart families that key tooltip executions per
1012
1118
  * sub-target (e.g. geo per-layer). `context` is required so the produced
1013
1119
  * lookup carries whatever the caller needs to interpret the result —
1014
1120
  * downstream code does not have to defensively check for missing context.
1015
1121
  *
1016
1122
  * @internal
1017
1123
  */
1018
- export declare function useTooltipLookupExecutions<TContext>(entries: readonly ITooltipLookupExecutionEntry<TContext>[], separators?: ISeparators, localizedStrings?: ITooltipLookupLocalizedStrings): Map<string, ITooltipLookupExecutionResult<TContext>>;
1124
+ export declare function useTooltipLookupExecutions<TContext>(entries: readonly ITooltipLookupExecutionEntry<TContext>[], separators?: ISeparators): Map<string, ITooltipLookupExecutionResult<TContext>>;
1019
1125
 
1020
1126
  /**
1021
1127
  * Returns the value if it is non-empty or a fallback text.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gooddata/sdk-ui-vis-commons",
3
- "version": "11.41.0-alpha.0",
3
+ "version": "11.41.0-alpha.1",
4
4
  "description": "GoodData.UI SDK - common functionality for different types of visualizations",
5
5
  "license": "MIT",
6
6
  "author": "GoodData Corporation",
@@ -36,11 +36,11 @@
36
36
  "react-intl": "7.1.11",
37
37
  "react-measure": "^2.5.2",
38
38
  "tslib": "2.8.1",
39
- "@gooddata/sdk-backend-spi": "11.41.0-alpha.0",
40
- "@gooddata/sdk-model": "11.41.0-alpha.0",
41
- "@gooddata/sdk-ui": "11.41.0-alpha.0",
42
- "@gooddata/sdk-ui-kit": "11.41.0-alpha.0",
43
- "@gooddata/sdk-ui-theme-provider": "11.41.0-alpha.0"
39
+ "@gooddata/sdk-backend-spi": "11.41.0-alpha.1",
40
+ "@gooddata/sdk-model": "11.41.0-alpha.1",
41
+ "@gooddata/sdk-ui": "11.41.0-alpha.1",
42
+ "@gooddata/sdk-ui-theme-provider": "11.41.0-alpha.1",
43
+ "@gooddata/sdk-ui-kit": "11.41.0-alpha.1"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@microsoft/api-documenter": "^7.17.0",
@@ -81,11 +81,11 @@
81
81
  "typescript": "5.9.3",
82
82
  "vitest": "4.1.8",
83
83
  "vitest-dom": "0.1.1",
84
- "@gooddata/eslint-config": "11.41.0-alpha.0",
85
- "@gooddata/oxlint-config": "11.41.0-alpha.0",
86
- "@gooddata/reference-workspace": "11.41.0-alpha.0",
87
- "@gooddata/sdk-backend-mockingbird": "11.41.0-alpha.0",
88
- "@gooddata/stylelint-config": "11.41.0-alpha.0"
84
+ "@gooddata/eslint-config": "11.41.0-alpha.1",
85
+ "@gooddata/oxlint-config": "11.41.0-alpha.1",
86
+ "@gooddata/sdk-backend-mockingbird": "11.41.0-alpha.1",
87
+ "@gooddata/stylelint-config": "11.41.0-alpha.1",
88
+ "@gooddata/reference-workspace": "11.41.0-alpha.1"
89
89
  },
90
90
  "peerDependencies": {
91
91
  "react": "^18.0.0 || ^19.0.0",