@sisense/sdk-ui 2.31.1 → 2.32.0

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.
Files changed (149) hide show
  1. package/dist/ai.cjs +2 -2
  2. package/dist/ai.js +9 -9
  3. package/dist/analytics-composer/node.cjs +1 -1
  4. package/dist/analytics-composer/node.js +5 -5
  5. package/dist/analytics-composer.cjs +1 -1
  6. package/dist/analytics-composer.js +6 -6
  7. package/dist/apply-styled-options-to-query-CE3WQwRs.cjs +1 -0
  8. package/dist/{apply-styled-options-to-query-lFlufwrB.js → apply-styled-options-to-query-TW3CqofD.js} +209 -207
  9. package/dist/{flow-DHowZLKN.cjs → const-BLmTd3gM.cjs} +1 -1
  10. package/dist/{flow-Cs53Uv2Y.js → const-vJfedJf9.js} +15 -15
  11. package/dist/execute-query-CZOWu-Fh.cjs +1 -0
  12. package/dist/{execute-query-4_76L7Ax.js → execute-query-D-gXk-LI.js} +908 -906
  13. package/dist/index-Boixy7N4.cjs +1 -0
  14. package/dist/{index-C2A2EHoh.cjs → index-C6ytYe3A.cjs} +1 -1
  15. package/dist/{index-eIOG6LP6.js → index-Ct7mA7YB.js} +1 -1
  16. package/dist/{index-CyVSfJ-B.js → index-D3DsBxkp.js} +22 -22
  17. package/dist/{index-DCYw3JUB.js → index-DrI_xqvr.js} +14 -0
  18. package/dist/{index-DTvxJdqZ.cjs → index-UssOwVVX.cjs} +1 -1
  19. package/dist/index.cjs +340 -340
  20. package/dist/index.js +12477 -12340
  21. package/dist/index.umd.js +805 -690
  22. package/dist/packages/sdk-ui/src/domains/dashboarding/common-filters/utils.d.ts +1 -1
  23. package/dist/packages/sdk-ui/src/domains/dashboarding/types.d.ts +22 -6
  24. package/dist/packages/sdk-ui/src/domains/query-execution/types.d.ts +2 -0
  25. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/components/regular-chart/has-no-results.d.ts +12 -0
  26. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/components/sisense-chart/sisense-chart.d.ts +1 -1
  27. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/components/sisense-chart/types.d.ts +8 -0
  28. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/helpers/use-chart-on-ready.d.ts +38 -0
  29. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/helpers/use-chart-renderer-props.d.ts +1 -0
  30. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/highchart-based-charts/highcharts-based-chart-renderer/highcharts-based-chart-renderer.d.ts +8 -0
  31. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/highchart-based-charts/sankey-chart/helpers/on-ready-state.d.ts +17 -0
  32. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/highchart-based-charts/sankey-chart/sankey-chart-builder.d.ts +8 -1
  33. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/kpi-chart/data/comparison.d.ts +22 -0
  34. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/kpi-chart/data/data.d.ts +17 -0
  35. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/kpi-chart/data/index.d.ts +4 -0
  36. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/kpi-chart/data/load-data.d.ts +64 -0
  37. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/kpi-chart/data/value-colors.d.ts +27 -0
  38. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/kpi-chart/data-options/data-options.d.ts +30 -0
  39. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/kpi-chart/data-options/index.d.ts +1 -0
  40. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/kpi-chart/design-options/design-options.d.ts +31 -0
  41. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/kpi-chart/design-options/index.d.ts +1 -0
  42. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/kpi-chart/kpi-chart-builder.d.ts +9 -0
  43. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/kpi-chart/renderer/helpers.d.ts +139 -0
  44. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/kpi-chart/renderer/index.d.ts +1 -0
  45. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/kpi-chart/renderer/kpi-card-styles.d.ts +154 -0
  46. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/kpi-chart/renderer/kpi-card.d.ts +41 -0
  47. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/kpi-chart/renderer/kpi-chart-renderer.d.ts +46 -0
  48. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/kpi-chart/renderer/kpi-comparison.d.ts +60 -0
  49. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/kpi-chart/renderer/kpi-sparkline.d.ts +23 -0
  50. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/kpi-chart/renderer/kpi-title.d.ts +28 -0
  51. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/kpi-chart/renderer/kpi-value.d.ts +55 -0
  52. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/kpi-chart/renderer/on-color.d.ts +70 -0
  53. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/kpi-chart/renderer/sparkline-options.d.ts +51 -0
  54. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/kpi-chart/renderer/use-auto-fit-font-size.d.ts +98 -0
  55. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/kpi-chart/renderer/use-element-size.d.ts +26 -0
  56. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/kpi-chart/renderer/use-size-tier.d.ts +19 -0
  57. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/kpi-chart/types.d.ts +62 -0
  58. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/restructured-charts/types.d.ts +47 -9
  59. package/dist/packages/sdk-ui/src/domains/visualizations/components/chart/types.d.ts +9 -0
  60. package/dist/packages/sdk-ui/src/domains/visualizations/components/kpi-chart.d.ts +23 -0
  61. package/dist/packages/sdk-ui/src/domains/visualizations/core/apply-on-ready-to-highcharts-options.d.ts +11 -0
  62. package/dist/packages/sdk-ui/src/domains/visualizations/core/chart-data/types.d.ts +2 -1
  63. package/dist/packages/sdk-ui/src/domains/visualizations/core/chart-data-options/types.d.ts +108 -2
  64. package/dist/packages/sdk-ui/src/domains/visualizations/core/chart-options-processor/chart-options-service.d.ts +1 -0
  65. package/dist/packages/sdk-ui/src/domains/visualizations/core/chart-options-processor/translations/design-options.d.ts +41 -1
  66. package/dist/packages/sdk-ui/src/domains/visualizations/core/chart-options-processor/translations/types.d.ts +17 -3
  67. package/dist/packages/sdk-ui/src/domains/visualizations/core/highcharts-renderer.d.ts +7 -1
  68. package/dist/packages/sdk-ui/src/domains/visualizations/core/query-definition/query-definition-style-constants.d.ts +1 -1
  69. package/dist/packages/sdk-ui/src/domains/widgets/components/chart-widget/types.d.ts +1 -2
  70. package/dist/packages/sdk-ui/src/domains/widgets/components/chart-widget/use-chart-widget-excel-download.d.ts +1 -1
  71. package/dist/packages/sdk-ui/src/domains/widgets/components/custom-widget/types.d.ts +1 -2
  72. package/dist/packages/sdk-ui/src/domains/widgets/components/filter-widget/filter-widget-dropdown.d.ts +16 -0
  73. package/dist/packages/sdk-ui/src/domains/widgets/components/filter-widget/types.d.ts +17 -23
  74. package/dist/packages/sdk-ui/src/domains/widgets/components/pivot-table-widget/types.d.ts +1 -2
  75. package/dist/packages/sdk-ui/src/domains/widgets/components/widget/types.d.ts +18 -4
  76. package/dist/packages/sdk-ui/src/domains/widgets/components/widget-by-id/translate-dashboard-filters.d.ts +447 -447
  77. package/dist/packages/sdk-ui/src/domains/widgets/components/widget-by-id/translate-panel-color-format.d.ts +8 -0
  78. package/dist/packages/sdk-ui/src/domains/widgets/components/widget-by-id/translate-widget-filters.d.ts +56 -56
  79. package/dist/packages/sdk-ui/src/domains/widgets/components/widget-by-id/translate-widget-style-options/categorical-labels-style.d.ts +3 -3
  80. package/dist/packages/sdk-ui/src/domains/widgets/components/widget-by-id/translate-widget-style-options/series-label-affix-style.d.ts +1 -1
  81. package/dist/packages/sdk-ui/src/domains/widgets/components/widget-by-id/translate-widget-style-options/to-widget-dto-style.d.ts +11 -2
  82. package/dist/packages/sdk-ui/src/domains/widgets/components/widget-by-id/types.d.ts +28 -5
  83. package/dist/packages/sdk-ui/src/domains/widgets/hooks/use-fire-on-ready.d.ts +14 -0
  84. package/dist/packages/sdk-ui/src/domains/widgets/widget-model/widget-model-translator/to-widget-dto-panels.d.ts +11 -1
  85. package/dist/packages/sdk-ui/src/infra/api/rest-api.d.ts +9 -2
  86. package/dist/packages/sdk-ui/src/infra/app/helpers.d.ts +23 -2
  87. package/dist/packages/sdk-ui/src/infra/app/settings/settings.d.ts +6 -3
  88. package/dist/packages/sdk-ui/src/infra/app/types.d.ts +14 -1
  89. package/dist/packages/sdk-ui/src/infra/translation/resources/__external__/de-de.d.ts +14 -0
  90. package/dist/packages/sdk-ui/src/infra/translation/resources/__external__/en-us.d.ts +14 -0
  91. package/dist/packages/sdk-ui/src/infra/translation/resources/__external__/es-ar.d.ts +14 -0
  92. package/dist/packages/sdk-ui/src/infra/translation/resources/__external__/es-es.d.ts +14 -0
  93. package/dist/packages/sdk-ui/src/infra/translation/resources/__external__/fr-fr.d.ts +14 -0
  94. package/dist/packages/sdk-ui/src/infra/translation/resources/__external__/it-it.d.ts +14 -0
  95. package/dist/packages/sdk-ui/src/infra/translation/resources/__external__/ja-jp.d.ts +14 -0
  96. package/dist/packages/sdk-ui/src/infra/translation/resources/__external__/ko-kr.d.ts +14 -0
  97. package/dist/packages/sdk-ui/src/infra/translation/resources/__external__/nl-nl.d.ts +14 -0
  98. package/dist/packages/sdk-ui/src/infra/translation/resources/__external__/pt-br.d.ts +14 -0
  99. package/dist/packages/sdk-ui/src/infra/translation/resources/__external__/ru-ru.d.ts +14 -0
  100. package/dist/packages/sdk-ui/src/infra/translation/resources/__external__/tr-tr.d.ts +14 -0
  101. package/dist/packages/sdk-ui/src/infra/translation/resources/__external__/zh-cn.d.ts +14 -0
  102. package/dist/packages/sdk-ui/src/infra/translation/resources/en.d.ts +14 -0
  103. package/dist/packages/sdk-ui/src/infra/translation/resources/index.d.ts +28 -0
  104. package/dist/packages/sdk-ui/src/props.d.ts +77 -5
  105. package/dist/packages/sdk-ui/src/public-api/beta.d.ts +4 -0
  106. package/dist/packages/sdk-ui/src/types.d.ts +296 -5
  107. package/dist/query.cjs +1 -1
  108. package/dist/query.js +3 -3
  109. package/dist/quota-notification-CdcItYEO.cjs +665 -0
  110. package/dist/{quota-notification-mCXOSF0U.js → quota-notification-DJPs09UQ.js} +17392 -15866
  111. package/dist/translations/de-de.cjs +1 -1
  112. package/dist/translations/de-de.js +15 -1
  113. package/dist/translations/en-us.cjs +1 -1
  114. package/dist/translations/en-us.js +1 -1
  115. package/dist/translations/es-ar.cjs +1 -1
  116. package/dist/translations/es-ar.js +15 -1
  117. package/dist/translations/es-es.cjs +1 -1
  118. package/dist/translations/es-es.js +15 -1
  119. package/dist/translations/fr-fr.cjs +1 -1
  120. package/dist/translations/fr-fr.js +17 -3
  121. package/dist/translations/it-it.cjs +1 -1
  122. package/dist/translations/it-it.js +15 -1
  123. package/dist/translations/ja-jp.cjs +1 -1
  124. package/dist/translations/ja-jp.js +15 -1
  125. package/dist/translations/ko-kr.cjs +1 -1
  126. package/dist/translations/ko-kr.js +15 -1
  127. package/dist/translations/nl-nl.cjs +1 -1
  128. package/dist/translations/nl-nl.js +15 -1
  129. package/dist/translations/pt-br.cjs +1 -1
  130. package/dist/translations/pt-br.js +15 -1
  131. package/dist/translations/ru-ru.cjs +1 -1
  132. package/dist/translations/ru-ru.js +15 -1
  133. package/dist/translations/tr-tr.cjs +1 -1
  134. package/dist/translations/tr-tr.js +15 -1
  135. package/dist/translations/zh-cn.cjs +1 -1
  136. package/dist/translations/zh-cn.js +15 -1
  137. package/dist/{types-CzQiy3kx.js → types-B60QjE1r.js} +1 -1
  138. package/dist/{types-pkCiWY_S.cjs → types-BAIldf5u.cjs} +1 -1
  139. package/dist/{use-execute-csv-query-DnTVUxCj.cjs → use-execute-csv-query-DAJqBzR5.cjs} +2 -2
  140. package/dist/{use-execute-csv-query-LtQrd2A4.js → use-execute-csv-query-tLJmsnwg.js} +6 -6
  141. package/dist/{utils-Bqaxp0gq.cjs → utils-BIAAcoFt.cjs} +12 -12
  142. package/dist/{utils-DHLPgrHF.js → utils-D2c9kOce.js} +1544 -1541
  143. package/dist/{widget-composer-CSkR-kBh.js → widget-composer-VWvON_Hi.js} +4 -4
  144. package/dist/{widget-composer-BUq7QhlK.cjs → widget-composer-srdW7lV4.cjs} +1 -1
  145. package/package.json +8 -8
  146. package/dist/apply-styled-options-to-query-siyJXPed.cjs +0 -1
  147. package/dist/execute-query-9rwu12er.cjs +0 -1
  148. package/dist/index-BGVJyEgp.cjs +0 -1
  149. package/dist/quota-notification-C49kSTz5.cjs +0 -550
@@ -0,0 +1,154 @@
1
+ /// <reference types="react" />
2
+ import { Themable } from '../../../../../../../infra/contexts/theme-provider/types.js';
3
+ /**
4
+ * Gap between {@link BodyArea}'s two children (value/comparison), in px. Exported so
5
+ * `kpi-chart-renderer.tsx` can subtract the exact same amount when computing the headline auto-fit
6
+ * height budget (`bodyHeight - compactSiblingHeight - BODY_GAP_PX`) -- the two must stay in sync,
7
+ * since a smaller JS-side allowance than the real CSS gap would under-budget (safe, just
8
+ * conservative) while a larger one would over-budget (risking the exact clipping this fixes).
9
+ * @internal
10
+ */
11
+ export declare const BODY_GAP_PX = 4;
12
+ /** Card block padding: start (top) and end (bottom), in px. @internal */
13
+ export declare const CARD_PADDING_BLOCK_START_PX = 14;
14
+ /** @internal */
15
+ export declare const CARD_PADDING_BLOCK_END_PX = 8;
16
+ /** Gap between the card's grid rows (title/body/sparkline), in px. @internal */
17
+ export declare const CARD_ROW_GAP_PX = 4;
18
+ /**
19
+ * The card's border width when `card.showBorder` is on, in px. `useElementSize` measures via
20
+ * `getBoundingClientRect` (border-inclusive), so the renderer must subtract this from both
21
+ * block edges of the figure-derived height budget whenever the border is shown.
22
+ * @internal
23
+ */
24
+ export declare const CARD_BORDER_PX = 1;
25
+ /**
26
+ * The sparkline row's minimum height, in px. With a sparkline present the row is
27
+ * `minmax(this, 1fr)` -- it absorbs all leftover height below the content group on tall cards,
28
+ * by design, but never shrinks below this floor.
29
+ * @internal
30
+ */
31
+ export declare const SPARKLINE_MIN_HEIGHT_PX = 32;
32
+ /** `ConditionalIconSpan`'s font size relative to its parent text. @internal */
33
+ export declare const CONDITIONAL_ICON_EM = 0.7;
34
+ /** `ConditionalIconSpan`'s margin-inline-end, in px. @internal */
35
+ export declare const CONDITIONAL_ICON_GAP_PX = 6;
36
+ /** `ComparisonArrow`'s font size relative to the comparison primary text. @internal */
37
+ export declare const COMPARISON_ARROW_EM = 0.85;
38
+ /** `ComparisonPrimaryText`'s flex gap between its items, in px. @internal */
39
+ export declare const COMPARISON_PRIMARY_GAP_PX = 3;
40
+ /** The KPI card's root figure element: the grid container laid out by {@link GRID_TEMPLATE}. @internal */
41
+ export declare const CardRoot: import("@emotion/styled").StyledComponent<{
42
+ theme?: import("@emotion/react").Theme | undefined;
43
+ as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
44
+ } & Themable & {
45
+ $backgroundColor?: string | undefined;
46
+ $textAlign: 'left' | 'center' | 'right';
47
+ $showBorder: boolean;
48
+ $cornerRadius: number;
49
+ $clickable: boolean;
50
+ $hasSparkline: boolean;
51
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLElement>, HTMLElement>, {}>;
52
+ /** The card's title row: the title text and, when present, the current-period caption. @internal */
53
+ export declare const TitleArea: import("@emotion/styled").StyledComponent<{
54
+ theme?: import("@emotion/react").Theme | undefined;
55
+ as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
56
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
57
+ /**
58
+ * Groups the headline value and the comparison readout into one tight vertical block, occupying
59
+ * the grid's flexible `body` row. Its two {@link BodySlot} children are `flex: 0 0 auto` (natural
60
+ * size, packed at the top with no gap-induced growth between them), so any leftover height in the
61
+ * (grid-determined, non-content-based) `body` row trails *after* the last child -- i.e. below the
62
+ * value/comparison pair, immediately before the sparkline -- rather than appearing as dead space
63
+ * between the title/value/comparison trio.
64
+ * @internal
65
+ */
66
+ export declare const BodyArea: import("@emotion/styled").StyledComponent<{
67
+ theme?: import("@emotion/react").Theme | undefined;
68
+ as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
69
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
70
+ /**
71
+ * Wraps one of `BodyArea`'s two children, ordering it per {@link CardLayout} (see `kpi-card.tsx`).
72
+ * @internal
73
+ */
74
+ export declare const BodySlot: import("@emotion/styled").StyledComponent<{
75
+ theme?: import("@emotion/react").Theme | undefined;
76
+ as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
77
+ } & {
78
+ $order: number;
79
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
80
+ /** Wraps `KpiValue`'s rendered output inside {@link BodyArea}. @internal */
81
+ export declare const ValueArea: import("@emotion/styled").StyledComponent<{
82
+ theme?: import("@emotion/react").Theme | undefined;
83
+ as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
84
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
85
+ /** Wraps `KpiComparison`'s rendered output inside {@link BodyArea}. @internal */
86
+ export declare const ComparisonArea: import("@emotion/styled").StyledComponent<{
87
+ theme?: import("@emotion/react").Theme | undefined;
88
+ as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
89
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
90
+ /**
91
+ * The card's sparkline row. Hidden from assistive tech by its consumer (`kpi-sparkline.tsx`);
92
+ * this element itself only owns the grid-area layout.
93
+ * @internal
94
+ */
95
+ export declare const SparklineArea: import("@emotion/styled").StyledComponent<{
96
+ theme?: import("@emotion/react").Theme | undefined;
97
+ as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
98
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
99
+ /** The card's title text, uppercased. @internal */
100
+ export declare const TitleText: import("@emotion/styled").StyledComponent<{
101
+ theme?: import("@emotion/react").Theme | undefined;
102
+ as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
103
+ } & Themable & {
104
+ $onColor: boolean;
105
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, {}>;
106
+ /** The current-period caption shown next to the title (e.g. `'Jun 2026'`). @internal */
107
+ export declare const PeriodText: import("@emotion/styled").StyledComponent<{
108
+ theme?: import("@emotion/react").Theme | undefined;
109
+ as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
110
+ } & Themable & {
111
+ $onColor: boolean;
112
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, {}>;
113
+ /** The card's headline value text. @internal */
114
+ export declare const ValueText: import("@emotion/styled").StyledComponent<{
115
+ theme?: import("@emotion/react").Theme | undefined;
116
+ as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
117
+ } & Themable & {
118
+ $onColor: boolean;
119
+ $color?: string | undefined;
120
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
121
+ /** Condition-driven icon rendered next to the headline value or the comparison readout. @internal */
122
+ export declare const ConditionalIconSpan: import("@emotion/styled").StyledComponent<{
123
+ theme?: import("@emotion/react").Theme | undefined;
124
+ as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
125
+ } & {
126
+ $color?: string | undefined;
127
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, {}>;
128
+ /** The comparison readout's root: row layout when `compact`, column layout otherwise. @internal */
129
+ export declare const ComparisonRoot: import("@emotion/styled").StyledComponent<{
130
+ theme?: import("@emotion/react").Theme | undefined;
131
+ as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
132
+ } & {
133
+ $compact: boolean;
134
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
135
+ /** The comparison readout's primary line (e.g. the delta/percent-of-goal text). @internal */
136
+ export declare const ComparisonPrimaryText: import("@emotion/styled").StyledComponent<{
137
+ theme?: import("@emotion/react").Theme | undefined;
138
+ as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
139
+ } & Themable & {
140
+ $color?: string | undefined;
141
+ $scale: 'compact' | 'headline';
142
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
143
+ /** The comparison readout's secondary line (e.g. the target label or amount-to-go text). @internal */
144
+ export declare const ComparisonSecondaryText: import("@emotion/styled").StyledComponent<{
145
+ theme?: import("@emotion/react").Theme | undefined;
146
+ as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
147
+ } & Themable & {
148
+ $onColor: boolean;
149
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
150
+ /** The up/down arrow glyph shown next to a delta-shaped comparison's primary text. @internal */
151
+ export declare const ComparisonArrow: import("@emotion/styled").StyledComponent<{
152
+ theme?: import("@emotion/react").Theme | undefined;
153
+ as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
154
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, {}>;
@@ -0,0 +1,41 @@
1
+ import { MouseEvent, ReactNode, RefObject } from 'react';
2
+ import { KpiChartDesignOptions } from '../../../../../../../domains/visualizations/core/chart-options-processor/translations/design-options.js';
3
+ import { KpiSizeTier } from './use-size-tier.js';
4
+ /**
5
+ * Defines the props of {@link KpiCard}.
6
+ * @internal
7
+ */
8
+ export type KpiCardProps = {
9
+ layout: KpiChartDesignOptions['layout'];
10
+ tier: KpiSizeTier;
11
+ ariaLabel: string;
12
+ card: KpiChartDesignOptions['card'];
13
+ /**
14
+ * Whether `onDataPointClick` or `onDataPointContextMenu` is wired up -- drives the pointer
15
+ * cursor and keyboard focusability, so a context-menu-only card is still reachable by keyboard
16
+ * even though Enter/Space only actuates a click.
17
+ */
18
+ clickable: boolean;
19
+ onClick?: (event: MouseEvent<HTMLElement>) => void;
20
+ onContextMenu?: (event: MouseEvent<HTMLElement>) => void;
21
+ title: ReactNode;
22
+ value: ReactNode;
23
+ comparison?: ReactNode;
24
+ sparkline?: ReactNode;
25
+ /**
26
+ * External ref to {@link BodyArea}, so the orchestrator can measure its grid-derived (safe,
27
+ * non-circular) height budget -- see `kpi-chart-renderer.tsx`'s `useElementSize(bodyRef)`.
28
+ */
29
+ bodyRef?: RefObject<HTMLDivElement | null>;
30
+ };
31
+ /**
32
+ * The KPI card's layout shell: a `<figure role="figure">` grid container that positions the
33
+ * title/value/comparison/sparkline subcomponents (passed in as already-rendered slots) and owns
34
+ * the card-level accessibility contract -- the composed `aria-label`, and, when clickable,
35
+ * keyboard activation (Enter/Space triggers the same native `click` the mouse handler listens
36
+ * for, via `element.click()`, so both paths share one code path and one correctly-typed
37
+ * `MouseEvent`). Groups `value`/`comparison` into a single {@link BodyArea} (see its TSDoc for
38
+ * why), ordered per `layout` via {@link valueOrderFor}/{@link comparisonOrderFor}.
39
+ * @internal
40
+ */
41
+ export declare const KpiCard: import("react").ForwardRefExoticComponent<KpiCardProps & import("react").RefAttributes<HTMLElement>>;
@@ -0,0 +1,46 @@
1
+ /// <reference types="react" />
2
+ import { ChartRendererProps } from '../../../../../../../domains/visualizations/components/chart/types.js';
3
+ import { KpiChartDataOptionsInternal } from '../../../../../../../domains/visualizations/core/chart-data-options/types.js';
4
+ import { KpiChartDesignOptions } from '../../../../../../../domains/visualizations/core/chart-options-processor/translations/design-options.js';
5
+ import { KpiChartData } from '../types.js';
6
+ /**
7
+ * Props accepted by the KPI chart renderer.
8
+ *
9
+ * NOTE: the event-handler fields are intentionally typed as the generic
10
+ * `ChartRendererProps` handler unions (rather than the narrower
11
+ * `KpiDataPointEventHandler` / `KpiBeforeRenderHandler` from `@/types.js`).
12
+ * `ChartProps`/`ChartEventProps` in `src/props.tsx` do carry KPI variants
13
+ * (added as part of the public KPI surface), but they're only one member of
14
+ * a larger union of per-chart-type handler signatures with incompatible
15
+ * point-argument shapes (e.g. `DataPoint`, `ScatterDataPoint`,
16
+ * `IndicatorDataPoint`, ...). Narrowing `KpiChartRendererProps` to the KPI
17
+ * handler types directly would make it unassignable to `ChartRendererProps`,
18
+ * which breaks the `isCorrectRendererProps` type predicate used by
19
+ * `ChartBuilder<'kpi'>`, so this component narrows internally instead (see
20
+ * the cast below).
21
+ * @internal
22
+ */
23
+ export type KpiChartRendererProps = {
24
+ chartData: KpiChartData;
25
+ dataOptions: KpiChartDataOptionsInternal;
26
+ designOptions: KpiChartDesignOptions;
27
+ onDataPointClick?: ChartRendererProps['onDataPointClick'];
28
+ onDataPointContextMenu?: ChartRendererProps['onDataPointContextMenu'];
29
+ onBeforeRender?: ChartRendererProps['onBeforeRender'];
30
+ };
31
+ /**
32
+ * KPI chart renderer.
33
+ *
34
+ * Composes the card shell ({@link KpiCard}) with its four subcomponents ({@link KpiTitle},
35
+ * {@link KpiValue}, {@link KpiComparison}, {@link KpiSparkline}), and owns everything that
36
+ * doesn't belong to a single subcomponent: the `onBeforeRender` pipeline, the no-data/no-results
37
+ * branch, size-tier-driven degradation, and the click/context-menu handlers.
38
+ * @internal
39
+ */
40
+ export declare const KpiChartRenderer: React.FC<KpiChartRendererProps>;
41
+ /**
42
+ * Checks whether the given generic chart renderer props are shaped as
43
+ * {@link KpiChartRendererProps}, narrowing on `chartData`, `dataOptions`, and `designOptions`.
44
+ * @internal
45
+ */
46
+ export declare const isKpiChartRendererProps: (props: ChartRendererProps) => props is KpiChartRendererProps;
@@ -0,0 +1,60 @@
1
+ import { RefObject } from 'react';
2
+ import type { KpiIconCondition, NumberFormatConfig } from '../../../../../../../types.js';
3
+ import { KpiComparisonDisplay } from './helpers.js';
4
+ /**
5
+ * Defines the props of {@link KpiComparison}.
6
+ * @internal
7
+ */
8
+ export type KpiComparisonProps = {
9
+ comparison: KpiComparisonDisplay;
10
+ /** Pre-resolved display color (via `resolveComparisonColor` for delta/target, or the data-driven color for `'value'`). */
11
+ color?: string;
12
+ /** Format config for the comparison's own numbers -- the `'value'` measure's format, or the headline's. */
13
+ numberFormatConfig?: NumberFormatConfig;
14
+ display: 'percent' | 'value' | 'both';
15
+ showIcon: boolean;
16
+ /**
17
+ * First matching condition-driven icon for the comparison readout, if any -- resolved by the
18
+ * renderer against the same metric the comparison color conditions evaluate (`deltaPercent` /
19
+ * `percentOfTarget`); mirrors the headline's `KpiValueProps.icon`.
20
+ */
21
+ conditionalIcon?: KpiIconCondition;
22
+ /** `designOptions.comparison.label` -- overrides the data-driven label when set. */
23
+ labelOverride?: string;
24
+ /**
25
+ * `'headline'` in the `'big-comparison'` layout, where the comparison takes over the headline
26
+ * role -- reading big and participating in auto-fit sizing exactly like the value does in the
27
+ * `'standard'` layout (mirrors `KpiValueProps.scale`). `'compact'` (the `'standard'` layout's
28
+ * default) keeps the fixed small readout.
29
+ */
30
+ scale: 'headline' | 'compact';
31
+ /**
32
+ * Collapses the two-line readout (value + label) onto a single line at the `'sm'`/`'xs'` tiers.
33
+ * Only honored at the `'compact'` scale: a `'headline'`-scale readout always stacks its label
34
+ * on its own line below the headline, so the label never competes with the auto-fitted
35
+ * headline for width.
36
+ */
37
+ compact: boolean;
38
+ onColor: boolean;
39
+ /**
40
+ * Non-circular height budget for the `'headline'` auto-fit computation, forwarded to
41
+ * {@link useAutoFitFontSize}'s `maxHeightPxOverride`. Required whenever `scale` is `'headline'`
42
+ * -- see `KpiValueProps.maxHeightPx`'s TSDoc for why `ComparisonArea`'s own box isn't a safe
43
+ * self-measurement target.
44
+ */
45
+ maxHeightPx?: number;
46
+ /**
47
+ * External ref to `ComparisonArea`, so the orchestrator can measure it (e.g. as the *other*
48
+ * sibling's height budget input when this component plays the `'compact'` role). Falls back to
49
+ * an internal ref when not supplied.
50
+ */
51
+ areaRef?: RefObject<HTMLDivElement | null>;
52
+ };
53
+ /**
54
+ * Renders the KPI card's comparison readout. Switches on {@link KpiComparisonDisplay}'s `type`:
55
+ * - `'previous-period'` / `'delta'`: an arrow plus the delta/percent (per `display`).
56
+ * - `'target'`: `'82% of goal'` + `'$250K to go'` (percent sign baked into the interpolation).
57
+ * - `'value'`: the label plus the comparison's own formatted number.
58
+ * @internal
59
+ */
60
+ export declare function KpiComparison({ comparison, color, numberFormatConfig, display, showIcon, conditionalIcon, labelOverride, scale, compact, onColor, maxHeightPx, areaRef, }: KpiComparisonProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,23 @@
1
+ import type { NumberFormatConfig } from '../../../../../../../types.js';
2
+ import { SparklineChartType, SparklinePoint } from './sparkline-options.js';
3
+ /**
4
+ * Defines the props of {@link KpiSparkline}.
5
+ * @internal
6
+ */
7
+ export type KpiSparklineProps = {
8
+ points: SparklinePoint[];
9
+ chartType: SparklineChartType;
10
+ color: string;
11
+ numberFormatConfig?: NumberFormatConfig;
12
+ };
13
+ /**
14
+ * Renders the KPI card's inline sparkline. Hidden from assistive tech (`aria-hidden`) since it's
15
+ * a decorative echo of data already conveyed by the headline value and comparison readout.
16
+ *
17
+ * The chart is given an explicit `chart.width`/`chart.height` measured from its own cell (via
18
+ * {@link useElementSize}'s `ResizeObserver`), re-applied whenever the cell resizes -- see
19
+ * {@link buildSparklineOptions}'s `size` param for why this is needed instead of relying on
20
+ * Highcharts' own container auto-detection.
21
+ * @internal
22
+ */
23
+ export declare function KpiSparkline({ points, chartType, color, numberFormatConfig }: KpiSparklineProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,28 @@
1
+ import { RefObject } from 'react';
2
+ /**
3
+ * Defines the props of {@link KpiTitle}.
4
+ * @internal
5
+ */
6
+ export type KpiTitleProps = {
7
+ /** Title text -- the design option override, or the value measure's own title. */
8
+ title: string;
9
+ /** Whether the title text is shown at all (`designOptions.title.enabled`). */
10
+ enabled: boolean;
11
+ /** Formatted current-period caption (e.g. `'Jun 2026'`), shown when the headline is a single bucket. */
12
+ period?: string;
13
+ /** Whether the card has a custom background, so text needs to contrast against it instead of the theme. */
14
+ onColor: boolean;
15
+ /**
16
+ * External ref to `TitleArea`, so the orchestrator can measure its height as an input to the
17
+ * headline auto-fit budget on sparkline cards (see `kpi-chart-renderer.tsx`). Stays unattached
18
+ * when the component renders nothing -- an absent title measures as zero, which is exactly
19
+ * what the budget arithmetic expects.
20
+ */
21
+ areaRef?: RefObject<HTMLDivElement | null>;
22
+ };
23
+ /**
24
+ * Renders the KPI card's header: the title text and, when present, the current-period caption.
25
+ * Renders nothing when there's neither a title to show nor a period caption.
26
+ * @internal
27
+ */
28
+ export declare function KpiTitle({ title, enabled, period, onColor, areaRef }: KpiTitleProps): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,55 @@
1
+ import { RefObject } from 'react';
2
+ import type { KpiIconCondition, KpiTextSize } from '../../../../../../../types.js';
3
+ /**
4
+ * Auto-fit corridor for whichever of value/comparison currently plays the "headline" role.
5
+ * Exported so `kpi-comparison.tsx` uses the exact same range when it plays that role instead
6
+ * (`layout: 'big-comparison'`), keeping the two visually interchangeable.
7
+ * @internal
8
+ */
9
+ export declare const AUTO_FIT_MIN_PX = 16;
10
+ /** @internal */
11
+ export declare const AUTO_FIT_MAX_PX = 64;
12
+ /**
13
+ * Defines the props of {@link KpiValue}.
14
+ * @internal
15
+ */
16
+ export type KpiValueProps = {
17
+ /** Already-formatted display text (the formatted value, or `designOptions.value.noDataText`). */
18
+ text: string;
19
+ /** Resolved display color: the measure's data-driven color (or an `onBeforeRender` override). */
20
+ color?: string;
21
+ /** `'auto'` for auto-fit sizing, or a fixed font size in px. */
22
+ textSize: KpiTextSize;
23
+ /** First matching conditional icon for the value, if any. */
24
+ icon?: KpiIconCondition;
25
+ onColor: boolean;
26
+ /**
27
+ * `'headline'` in the `'standard'` layout, where the value reads big and participates in
28
+ * auto-fit sizing; `'compact'` in `'big-comparison'`, where the comparison takes the headline
29
+ * role instead and the value renders small (mirrors `KpiComparisonProps.scale`). Only affects
30
+ * sizing when `textSize` is `'auto'` -- an explicit fixed `textSize` always wins.
31
+ */
32
+ scale: 'headline' | 'compact';
33
+ /**
34
+ * Non-circular height budget for the `'headline'` auto-fit computation, forwarded to
35
+ * {@link useAutoFitFontSize}'s `maxHeightPxOverride`. Required whenever `scale` is
36
+ * `'headline'`, since `ValueArea`'s own box is `flex: 0 0 auto` (content-sized) inside
37
+ * `BodyArea`, not a safe self-measurement target -- see that hook's TSDoc for why.
38
+ */
39
+ maxHeightPx?: number;
40
+ /**
41
+ * External ref to `ValueArea`, so the orchestrator can measure it (e.g. as the *other*
42
+ * sibling's height budget input when this component plays the `'compact'` role). Falls back to
43
+ * an internal ref when not supplied.
44
+ */
45
+ areaRef?: RefObject<HTMLDivElement | null>;
46
+ };
47
+ /**
48
+ * Renders the KPI card's headline value, auto-fitting its font size to the available box when
49
+ * `textSize` is `'auto'` and `scale` is `'headline'`. A conditional icon shares the value's
50
+ * nowrap box, so it's budgeted into the fit as an {@link AutoFitAffix} (its glyph is em-scaled
51
+ * with the fitted font; its margin is fixed px) -- otherwise the icon's width would push the
52
+ * text into `text-overflow: ellipsis` at exactly the size the fit claimed was safe.
53
+ * @internal
54
+ */
55
+ export declare function KpiValue({ text, color, textSize, icon, onColor, scale, maxHeightPx, areaRef, }: KpiValueProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Relative luminance (0 = black, 1 = white) below which a background color is treated as dark
3
+ * enough that the card's headline text and sparkline should switch to white for contrast.
4
+ * 0.179 is the WCAG crossover point: white text has a higher contrast ratio than black text
5
+ * exactly when the background's relative luminance L satisfies `(1.05) / (L + 0.05) >
6
+ * (L + 0.05) / 0.05`, i.e. below `sqrt(1.05 * 0.05) - 0.05 ~= 0.179`. Mid-gray backgrounds
7
+ * (e.g. `#999999`, luminance ~0.32) therefore keep dark text instead of forcing white at a
8
+ * failing ~2.85:1 ratio.
9
+ * @internal
10
+ */
11
+ export declare const DARK_BACKGROUND_LUMINANCE_THRESHOLD = 0.179;
12
+ /** A color's channels, each 0-255 except `a`, which is 0-1. */
13
+ type Rgba = {
14
+ r: number;
15
+ g: number;
16
+ b: number;
17
+ a: number;
18
+ };
19
+ /**
20
+ * Parses a hex color string (`#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa`) into its channels, or
21
+ * `undefined` when `color` doesn't match a hex color at all (named colors like `'green'`,
22
+ * functional notations like `rgb()`/`hsl()`, or an empty/missing value).
23
+ * @internal
24
+ */
25
+ export declare function parseHexColor(color: string | undefined): Rgba | undefined;
26
+ /**
27
+ * Computes the WCAG relative luminance of a hex color string (0 = black, 1 = white), or
28
+ * `undefined` when the color can't be parsed as hex, or is mostly transparent (alpha below 0.5)
29
+ * -- a mostly-transparent background shows whatever is behind the card, so there's no reliable
30
+ * color to measure contrast against.
31
+ * @internal
32
+ */
33
+ export declare function relativeLuminance(color: string | undefined): number | undefined;
34
+ /**
35
+ * Whether the card's headline text and sparkline should render in white for contrast against
36
+ * `backgroundColor`, instead of forcing white on any custom background regardless of how light
37
+ * it is (the bug this replaces). Only `true` for a background that both parses as a hex color
38
+ * and is dark enough ({@link relativeLuminance} below {@link DARK_BACKGROUND_LUMINANCE_THRESHOLD});
39
+ * an unset, unparseable (named color, `rgb()`/`hsl()`), or mostly transparent background falls
40
+ * back to `false` (the theme's own text color) rather than a guess that could make text invisible.
41
+ * @internal
42
+ */
43
+ export declare function resolveOnColor(backgroundColor: string | undefined): boolean;
44
+ /**
45
+ * Minimum WCAG contrast ratio for non-text graphics (WCAG 1.4.11), used to decide whether the
46
+ * theme's accent color is legible for the sparkline against a custom card background.
47
+ * @internal
48
+ */
49
+ export declare const GRAPHICS_MIN_CONTRAST_RATIO = 3;
50
+ /**
51
+ * Computes the WCAG contrast ratio (1-21) between two hex colors, or `undefined` when either
52
+ * color can't be measured ({@link relativeLuminance} returns `undefined` for it).
53
+ * @internal
54
+ */
55
+ export declare function contrastRatio(a: string | undefined, b: string | undefined): number | undefined;
56
+ /**
57
+ * Resolves the sparkline color against a custom card background: keeps the theme `accent` when
58
+ * it is legible (contrast ratio of at least {@link GRAPHICS_MIN_CONTRAST_RATIO}, per WCAG 1.4.11
59
+ * for graphics), and otherwise falls back to whichever of the theme `textColor` or white reads
60
+ * better against the background. With no custom background -- or one that can't be measured
61
+ * (named color, `rgb()`, mostly transparent) -- the accent is returned unchanged, matching the
62
+ * text behavior of {@link resolveOnColor}.
63
+ * @internal
64
+ */
65
+ export declare function resolveSparklineColor(options: {
66
+ accent: string;
67
+ textColor: string;
68
+ backgroundColor: string | undefined;
69
+ }): string;
70
+ export {};
@@ -0,0 +1,51 @@
1
+ import Highcharts from '@sisense/sisense-charts';
2
+ import type { NumberFormatConfig } from '../../../../../../../types.js';
3
+ /**
4
+ * A sparkline data point; a `null` `y` is a gap in the line/area, never rendered as zero.
5
+ *
6
+ * @internal
7
+ */
8
+ export type SparklinePoint = {
9
+ x: number;
10
+ y: number | null;
11
+ };
12
+ /**
13
+ * Chart type the sparkline is drawn as.
14
+ *
15
+ * @internal
16
+ */
17
+ export type SparklineChartType = 'line' | 'spline' | 'area' | 'column';
18
+ /**
19
+ * Formatting inputs for the sparkline's tooltip.
20
+ *
21
+ * @internal
22
+ */
23
+ export type SparklineFormatting = {
24
+ /** Format config for the `y` value, matching the headline measure's own format. */
25
+ numberFormatConfig?: NumberFormatConfig;
26
+ /** Formats the point's `x` (an epoch-ms date) for the tooltip; omitted when there's no date axis. */
27
+ formatDate?: (epochMs: number) => string;
28
+ };
29
+ /**
30
+ * Builds the Highcharts options for the KPI card's inline sparkline.
31
+ *
32
+ * `'spline'` is a core Highcharts series type -- it's registered directly inside `highcharts.js`
33
+ * (unlike `heatmap`/`sankey`/`streamgraph`/`series-label`, which are separate modules applied in
34
+ * `highcharts-overrides.ts`) -- so no extra module import is needed to support it here.
35
+ * @param points - Sparkline data; `null` `y` values are preserved as gaps.
36
+ * @param chartType - Series type to render.
37
+ * @param color - Series (and, for `'area'`, gradient fill) color.
38
+ * @param formatting - Tooltip formatting inputs.
39
+ * @param size - Explicit pixel size for the chart, measured from its cell. `HighchartsReact`'s
40
+ * container div never triggers a Highcharts reflow on its own resize (only on a window resize),
41
+ * so without an explicit `chart.width`/`chart.height` the chart can settle at Highcharts'
42
+ * hardcoded 600x400 default instead of the cell's actual (often much smaller) size. Omitted
43
+ * before the cell has been measured, letting Highcharts fall back to its own auto-detection for
44
+ * the very first paint.
45
+ * @returns Highcharts options for the sparkline, with mouse tracking and a tooltip enabled.
46
+ * @internal
47
+ */
48
+ export declare function buildSparklineOptions(points: SparklinePoint[], chartType: SparklineChartType, color: string, formatting?: SparklineFormatting, size?: {
49
+ width: number;
50
+ height: number;
51
+ }): Highcharts.Options;
@@ -0,0 +1,98 @@
1
+ import { RefObject } from 'react';
2
+ /**
3
+ * An inline decoration that shares the auto-fitted text's nowrap box and therefore consumes
4
+ * width the text itself cannot use -- e.g. a conditional icon next to the headline value, or
5
+ * the trend arrow before a headline-scale comparison delta. Affix glyphs are styled in em
6
+ * units, so their width scales with the fitted font and must be budgeted proportionally; their
7
+ * margins/flex gaps are fixed px.
8
+ * @internal
9
+ */
10
+ export type AutoFitAffix = {
11
+ /** The affix's text content (e.g. the icon glyph or the arrow character). */
12
+ text: string;
13
+ /** The affix's font size relative to the fitted text's, e.g. `0.7` for a 0.7em icon. */
14
+ emScale: number;
15
+ /** Fixed spacing the affix adds (margins plus flex gaps), in px. */
16
+ gapPx: number;
17
+ };
18
+ /**
19
+ * Computes the font size (px) that fits `text` (plus any {@link AutoFitAffix}es sharing its
20
+ * box) into a `maxWidthPx` x `maxHeightPx` box.
21
+ *
22
+ * The width bound is derived by measuring `text` -- and each affix at its em-scaled size --
23
+ * at a {@link PROBE_FONT_SIZE_PX} probe font size (via canvas `measureText`, or the injected
24
+ * `measure`) and scaling that composite measurement to `maxWidthPx` minus the affixes' fixed
25
+ * gaps. The height bound is `maxHeightPx` divided by the {@link LINE_HEIGHT_FACTOR}
26
+ * line-height. The tighter of the two bounds is clamped to `[minPx, maxPx]`, floored to a
27
+ * whole pixel, and then VERIFIED: the composite is re-measured at the candidate size itself
28
+ * and stepped down proportionally if it turns out wider than `maxWidthPx` (extrapolation from
29
+ * the probe is near-linear but not exact -- hinting differs per size -- and `text-overflow:
30
+ * ellipsis` clips on ANY overflow, sub-pixel included). The whole-px floor doubles as a
31
+ * fractional-pixel safety margin against that same sub-pixel clipping.
32
+ * @param opts - Fit parameters.
33
+ * @param opts.text - The text to fit.
34
+ * @param opts.font - Font family and weight used to build the probe CSS font string.
35
+ * @param opts.maxWidthPx - Available width, in CSS pixels.
36
+ * @param opts.maxHeightPx - Available height, in CSS pixels.
37
+ * @param opts.minPx - Lower bound for the returned font size.
38
+ * @param opts.maxPx - Upper bound for the returned font size.
39
+ * @param opts.measure - Measures a string's rendered width (px) for a given CSS font
40
+ * shorthand string. Defaults to canvas `measureText`; injectable for tests.
41
+ * @param opts.affixes - Inline decorations sharing the text's box, budgeted into the fit.
42
+ * @returns The fitted font size, in CSS pixels, clamped to `[minPx, maxPx]`.
43
+ * @internal
44
+ */
45
+ export declare function computeAutoFitFontSize(opts: {
46
+ text: string;
47
+ font: {
48
+ family: string;
49
+ weight: string | number;
50
+ };
51
+ maxWidthPx: number;
52
+ maxHeightPx: number;
53
+ minPx: number;
54
+ maxPx: number;
55
+ measure?: (text: string, cssFont: string) => number;
56
+ affixes?: readonly AutoFitAffix[];
57
+ }): number;
58
+ /**
59
+ * Computes a KPI headline's auto-fit font size, re-measuring the `containerRef` element's
60
+ * box on resize, and once more whenever `text`/`font`/`minPx`/`maxPx` change (even without
61
+ * a resize).
62
+ * @param params - Fit parameters.
63
+ * @param params.containerRef - Ref to the element whose box the text must fit inside.
64
+ * @param params.text - The text to fit.
65
+ * @param params.font - Font family and weight used for measurement.
66
+ * @param params.minPx - Lower bound for the returned font size.
67
+ * @param params.maxPx - Upper bound for the returned font size.
68
+ * @param params.measure - Forwarded to {@link computeAutoFitFontSize}; injectable for tests.
69
+ * @param params.maxHeightPxOverride - When provided, used as the height bound instead of
70
+ * `containerRef.current.clientHeight`. Needed whenever the container's own box is NOT a safe
71
+ * (non-circular) height reference -- e.g. a flex row that grows to fill its sibling's leftover
72
+ * space, whose rendered height would otherwise track the very font size being computed here,
73
+ * oscillating toward `minPx` instead of the true available height. Width is always measured
74
+ * from `containerRef.current.clientWidth`, which has no such circularity.
75
+ * @param params.enabled - Pass `false` when the caller doesn't currently consume the result
76
+ * (e.g. a KPI subcomponent rendered at its fixed 'compact' scale) to skip the ResizeObserver,
77
+ * canvas measurement, and font-availability watch entirely. Defaults to `true`. The hook still
78
+ * runs (rules of hooks); it just returns `minPx` and performs no work.
79
+ * @param params.affixes - Forwarded to {@link computeAutoFitFontSize}: inline decorations
80
+ * (icons, arrows) sharing the text's box, budgeted into the fit. Compared by value across
81
+ * renders -- fresh array literals are fine.
82
+ * @returns The fitted font size, in CSS pixels. `minPx` until the container is measured.
83
+ * @internal
84
+ */
85
+ export declare function useAutoFitFontSize(params: {
86
+ containerRef: RefObject<HTMLElement | null>;
87
+ text: string;
88
+ font: {
89
+ family: string;
90
+ weight: string | number;
91
+ };
92
+ minPx: number;
93
+ maxPx: number;
94
+ measure?: (text: string, cssFont: string) => number;
95
+ maxHeightPxOverride?: number;
96
+ enabled?: boolean;
97
+ affixes?: readonly AutoFitAffix[];
98
+ }): number;