@automattic/charts 0.58.0 → 1.0.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 (253) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +7 -54
  3. package/dist/index.cjs +9606 -22
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.css +20 -25
  6. package/dist/index.css.map +1 -1
  7. package/dist/index.d.cts +1612 -33
  8. package/dist/index.d.ts +1612 -33
  9. package/dist/index.js +9640 -56
  10. package/dist/index.js.map +1 -1
  11. package/package.json +8 -125
  12. package/src/charts/bar-chart/bar-chart.module.scss +0 -5
  13. package/src/charts/bar-chart/bar-chart.tsx +131 -137
  14. package/src/charts/leaderboard-chart/leaderboard-chart.tsx +23 -40
  15. package/src/charts/line-chart/line-chart.module.scss +0 -5
  16. package/src/charts/line-chart/line-chart.tsx +190 -183
  17. package/src/charts/line-chart/private/line-chart-annotations-overlay.tsx +1 -2
  18. package/src/charts/pie-chart/pie-chart.module.scss +2 -10
  19. package/src/charts/pie-chart/pie-chart.tsx +198 -199
  20. package/src/charts/pie-chart/test/composition-api.test.tsx +3 -3
  21. package/src/charts/pie-chart/test/pie-chart.test.tsx +42 -35
  22. package/src/charts/pie-semi-circle-chart/pie-semi-circle-chart.module.scss +2 -8
  23. package/src/charts/pie-semi-circle-chart/pie-semi-circle-chart.tsx +155 -155
  24. package/src/charts/pie-semi-circle-chart/test/pie-semi-circle-chart.test.tsx +25 -25
  25. package/src/charts/private/chart-layout/chart-layout.module.scss +7 -0
  26. package/src/charts/private/chart-layout/chart-layout.tsx +106 -0
  27. package/src/charts/private/chart-layout/index.ts +2 -0
  28. package/src/charts/private/chart-layout/test/chart-layout.test.tsx +167 -0
  29. package/src/charts/private/single-chart-context/single-chart-context.tsx +2 -2
  30. package/src/charts/private/svg-empty-state/index.ts +1 -0
  31. package/src/charts/private/svg-empty-state/svg-empty-state.module.scss +7 -0
  32. package/src/charts/private/svg-empty-state/svg-empty-state.tsx +40 -0
  33. package/src/components/legend/hooks/test/use-chart-legend-items.test.tsx +12 -8
  34. package/src/components/legend/hooks/use-chart-legend-items.ts +12 -13
  35. package/src/components/legend/legend.tsx +33 -8
  36. package/src/components/legend/test/legend.test.tsx +93 -1
  37. package/src/hooks/index.ts +1 -0
  38. package/src/hooks/use-data-with-percentages.ts +24 -0
  39. package/src/hooks/use-interactive-legend-data.ts +18 -15
  40. package/src/index.ts +65 -2
  41. package/src/providers/chart-context/global-charts-provider.tsx +7 -1
  42. package/src/providers/chart-context/hooks/use-chart-registration.ts +2 -1
  43. package/src/providers/chart-context/types.ts +2 -2
  44. package/src/types.ts +27 -7
  45. package/src/utils/test/resolve-css-var.test.ts +2 -0
  46. package/dist/base-tooltip-DOq93wjU.d.cts +0 -38
  47. package/dist/base-tooltip-DOq93wjU.d.ts +0 -38
  48. package/dist/charts/bar-chart/index.cjs +0 -17
  49. package/dist/charts/bar-chart/index.cjs.map +0 -1
  50. package/dist/charts/bar-chart/index.css +0 -141
  51. package/dist/charts/bar-chart/index.css.map +0 -1
  52. package/dist/charts/bar-chart/index.d.cts +0 -36
  53. package/dist/charts/bar-chart/index.d.ts +0 -36
  54. package/dist/charts/bar-chart/index.js +0 -17
  55. package/dist/charts/bar-chart/index.js.map +0 -1
  56. package/dist/charts/bar-list-chart/index.cjs +0 -18
  57. package/dist/charts/bar-list-chart/index.cjs.map +0 -1
  58. package/dist/charts/bar-list-chart/index.css +0 -141
  59. package/dist/charts/bar-list-chart/index.css.map +0 -1
  60. package/dist/charts/bar-list-chart/index.d.cts +0 -92
  61. package/dist/charts/bar-list-chart/index.d.ts +0 -92
  62. package/dist/charts/bar-list-chart/index.js +0 -18
  63. package/dist/charts/bar-list-chart/index.js.map +0 -1
  64. package/dist/charts/conversion-funnel-chart/index.cjs +0 -11
  65. package/dist/charts/conversion-funnel-chart/index.cjs.map +0 -1
  66. package/dist/charts/conversion-funnel-chart/index.css +0 -157
  67. package/dist/charts/conversion-funnel-chart/index.css.map +0 -1
  68. package/dist/charts/conversion-funnel-chart/index.d.cts +0 -97
  69. package/dist/charts/conversion-funnel-chart/index.d.ts +0 -97
  70. package/dist/charts/conversion-funnel-chart/index.js +0 -11
  71. package/dist/charts/conversion-funnel-chart/index.js.map +0 -1
  72. package/dist/charts/geo-chart/index.cjs +0 -13
  73. package/dist/charts/geo-chart/index.cjs.map +0 -1
  74. package/dist/charts/geo-chart/index.css +0 -23
  75. package/dist/charts/geo-chart/index.css.map +0 -1
  76. package/dist/charts/geo-chart/index.d.cts +0 -67
  77. package/dist/charts/geo-chart/index.d.ts +0 -67
  78. package/dist/charts/geo-chart/index.js +0 -13
  79. package/dist/charts/geo-chart/index.js.map +0 -1
  80. package/dist/charts/leaderboard-chart/index.cjs +0 -21
  81. package/dist/charts/leaderboard-chart/index.cjs.map +0 -1
  82. package/dist/charts/leaderboard-chart/index.css +0 -160
  83. package/dist/charts/leaderboard-chart/index.css.map +0 -1
  84. package/dist/charts/leaderboard-chart/index.d.cts +0 -46
  85. package/dist/charts/leaderboard-chart/index.d.ts +0 -46
  86. package/dist/charts/leaderboard-chart/index.js +0 -21
  87. package/dist/charts/leaderboard-chart/index.js.map +0 -1
  88. package/dist/charts/line-chart/index.cjs +0 -17
  89. package/dist/charts/line-chart/index.cjs.map +0 -1
  90. package/dist/charts/line-chart/index.css +0 -213
  91. package/dist/charts/line-chart/index.css.map +0 -1
  92. package/dist/charts/line-chart/index.d.cts +0 -98
  93. package/dist/charts/line-chart/index.d.ts +0 -98
  94. package/dist/charts/line-chart/index.js +0 -17
  95. package/dist/charts/line-chart/index.js.map +0 -1
  96. package/dist/charts/pie-chart/index.cjs +0 -19
  97. package/dist/charts/pie-chart/index.cjs.map +0 -1
  98. package/dist/charts/pie-chart/index.css +0 -131
  99. package/dist/charts/pie-chart/index.css.map +0 -1
  100. package/dist/charts/pie-chart/index.d.cts +0 -91
  101. package/dist/charts/pie-chart/index.d.ts +0 -91
  102. package/dist/charts/pie-chart/index.js +0 -19
  103. package/dist/charts/pie-chart/index.js.map +0 -1
  104. package/dist/charts/pie-semi-circle-chart/index.cjs +0 -18
  105. package/dist/charts/pie-semi-circle-chart/index.cjs.map +0 -1
  106. package/dist/charts/pie-semi-circle-chart/index.css +0 -132
  107. package/dist/charts/pie-semi-circle-chart/index.css.map +0 -1
  108. package/dist/charts/pie-semi-circle-chart/index.d.cts +0 -88
  109. package/dist/charts/pie-semi-circle-chart/index.d.ts +0 -88
  110. package/dist/charts/pie-semi-circle-chart/index.js +0 -18
  111. package/dist/charts/pie-semi-circle-chart/index.js.map +0 -1
  112. package/dist/charts/sparkline/index.cjs +0 -18
  113. package/dist/charts/sparkline/index.cjs.map +0 -1
  114. package/dist/charts/sparkline/index.css +0 -230
  115. package/dist/charts/sparkline/index.css.map +0 -1
  116. package/dist/charts/sparkline/index.d.cts +0 -113
  117. package/dist/charts/sparkline/index.d.ts +0 -113
  118. package/dist/charts/sparkline/index.js +0 -18
  119. package/dist/charts/sparkline/index.js.map +0 -1
  120. package/dist/chunk-2A34OA5O.cjs +0 -51
  121. package/dist/chunk-2A34OA5O.cjs.map +0 -1
  122. package/dist/chunk-2I67QUIV.js +0 -895
  123. package/dist/chunk-2I67QUIV.js.map +0 -1
  124. package/dist/chunk-2ICEEQOC.js +0 -1071
  125. package/dist/chunk-2ICEEQOC.js.map +0 -1
  126. package/dist/chunk-4B7BL2DD.js +0 -120
  127. package/dist/chunk-4B7BL2DD.js.map +0 -1
  128. package/dist/chunk-4OXMTKAL.js +0 -401
  129. package/dist/chunk-4OXMTKAL.js.map +0 -1
  130. package/dist/chunk-ASLARV7L.cjs +0 -81
  131. package/dist/chunk-ASLARV7L.cjs.map +0 -1
  132. package/dist/chunk-B6NLZFRW.js +0 -617
  133. package/dist/chunk-B6NLZFRW.js.map +0 -1
  134. package/dist/chunk-BBAUQOW6.cjs +0 -120
  135. package/dist/chunk-BBAUQOW6.cjs.map +0 -1
  136. package/dist/chunk-BPYKWMI7.js +0 -194
  137. package/dist/chunk-BPYKWMI7.js.map +0 -1
  138. package/dist/chunk-CMMHCTBX.cjs +0 -373
  139. package/dist/chunk-CMMHCTBX.cjs.map +0 -1
  140. package/dist/chunk-CPPXJATQ.cjs +0 -1071
  141. package/dist/chunk-CPPXJATQ.cjs.map +0 -1
  142. package/dist/chunk-DKU775VC.js +0 -219
  143. package/dist/chunk-DKU775VC.js.map +0 -1
  144. package/dist/chunk-GRA7Y2ZG.cjs +0 -401
  145. package/dist/chunk-GRA7Y2ZG.cjs.map +0 -1
  146. package/dist/chunk-I2276W3I.cjs +0 -66
  147. package/dist/chunk-I2276W3I.cjs.map +0 -1
  148. package/dist/chunk-JJIMABHT.js +0 -351
  149. package/dist/chunk-JJIMABHT.js.map +0 -1
  150. package/dist/chunk-KJHWXOCZ.js +0 -421
  151. package/dist/chunk-KJHWXOCZ.js.map +0 -1
  152. package/dist/chunk-KRWGSOJ2.js +0 -91
  153. package/dist/chunk-KRWGSOJ2.js.map +0 -1
  154. package/dist/chunk-KXRWNFQJ.js +0 -51
  155. package/dist/chunk-KXRWNFQJ.js.map +0 -1
  156. package/dist/chunk-LTFH7SEG.js +0 -373
  157. package/dist/chunk-LTFH7SEG.js.map +0 -1
  158. package/dist/chunk-MUNOKLLE.js +0 -165
  159. package/dist/chunk-MUNOKLLE.js.map +0 -1
  160. package/dist/chunk-MXGLYWVP.cjs +0 -351
  161. package/dist/chunk-MXGLYWVP.cjs.map +0 -1
  162. package/dist/chunk-OP6PHB2U.js +0 -81
  163. package/dist/chunk-OP6PHB2U.js.map +0 -1
  164. package/dist/chunk-OYC34VTO.cjs +0 -3957
  165. package/dist/chunk-OYC34VTO.cjs.map +0 -1
  166. package/dist/chunk-PQL5I3F6.cjs +0 -421
  167. package/dist/chunk-PQL5I3F6.cjs.map +0 -1
  168. package/dist/chunk-REZTQ4PH.cjs +0 -488
  169. package/dist/chunk-REZTQ4PH.cjs.map +0 -1
  170. package/dist/chunk-TZRUHQOH.cjs +0 -91
  171. package/dist/chunk-TZRUHQOH.cjs.map +0 -1
  172. package/dist/chunk-UTYVIOWZ.js +0 -3957
  173. package/dist/chunk-UTYVIOWZ.js.map +0 -1
  174. package/dist/chunk-W2LDIX26.cjs +0 -165
  175. package/dist/chunk-W2LDIX26.cjs.map +0 -1
  176. package/dist/chunk-WSG64BVN.cjs +0 -219
  177. package/dist/chunk-WSG64BVN.cjs.map +0 -1
  178. package/dist/chunk-WTQYGUNF.js +0 -400
  179. package/dist/chunk-WTQYGUNF.js.map +0 -1
  180. package/dist/chunk-WYK7EL5R.cjs +0 -895
  181. package/dist/chunk-WYK7EL5R.cjs.map +0 -1
  182. package/dist/chunk-XC4KHJYX.cjs +0 -617
  183. package/dist/chunk-XC4KHJYX.cjs.map +0 -1
  184. package/dist/chunk-XVBH5XHE.cjs +0 -400
  185. package/dist/chunk-XVBH5XHE.cjs.map +0 -1
  186. package/dist/chunk-XWYZIFZW.js +0 -66
  187. package/dist/chunk-XWYZIFZW.js.map +0 -1
  188. package/dist/chunk-Y3NNQMAX.cjs +0 -194
  189. package/dist/chunk-Y3NNQMAX.cjs.map +0 -1
  190. package/dist/chunk-YAFQVVDI.js +0 -488
  191. package/dist/chunk-YAFQVVDI.js.map +0 -1
  192. package/dist/components/legend/index.cjs +0 -12
  193. package/dist/components/legend/index.cjs.map +0 -1
  194. package/dist/components/legend/index.css +0 -91
  195. package/dist/components/legend/index.css.map +0 -1
  196. package/dist/components/legend/index.d.cts +0 -37
  197. package/dist/components/legend/index.d.ts +0 -37
  198. package/dist/components/legend/index.js +0 -12
  199. package/dist/components/legend/index.js.map +0 -1
  200. package/dist/components/tooltip/index.cjs +0 -12
  201. package/dist/components/tooltip/index.cjs.map +0 -1
  202. package/dist/components/tooltip/index.css +0 -13
  203. package/dist/components/tooltip/index.css.map +0 -1
  204. package/dist/components/tooltip/index.d.cts +0 -71
  205. package/dist/components/tooltip/index.d.ts +0 -71
  206. package/dist/components/tooltip/index.js +0 -12
  207. package/dist/components/tooltip/index.js.map +0 -1
  208. package/dist/components/trend-indicator/index.cjs +0 -8
  209. package/dist/components/trend-indicator/index.cjs.map +0 -1
  210. package/dist/components/trend-indicator/index.css +0 -27
  211. package/dist/components/trend-indicator/index.css.map +0 -1
  212. package/dist/components/trend-indicator/index.d.cts +0 -44
  213. package/dist/components/trend-indicator/index.d.ts +0 -44
  214. package/dist/components/trend-indicator/index.js +0 -8
  215. package/dist/components/trend-indicator/index.js.map +0 -1
  216. package/dist/format-metric-value-MXm5DtQ_.d.cts +0 -24
  217. package/dist/format-metric-value-MXm5DtQ_.d.ts +0 -24
  218. package/dist/hooks/index.cjs +0 -29
  219. package/dist/hooks/index.cjs.map +0 -1
  220. package/dist/hooks/index.css +0 -9
  221. package/dist/hooks/index.css.map +0 -1
  222. package/dist/hooks/index.d.cts +0 -264
  223. package/dist/hooks/index.d.ts +0 -264
  224. package/dist/hooks/index.js +0 -29
  225. package/dist/hooks/index.js.map +0 -1
  226. package/dist/leaderboard-chart-BSbg0ufV.d.cts +0 -79
  227. package/dist/leaderboard-chart-odEYxxEC.d.ts +0 -79
  228. package/dist/legend-DFkosEvC.d.cts +0 -9
  229. package/dist/legend-DLswHhOk.d.ts +0 -9
  230. package/dist/providers/index.cjs +0 -21
  231. package/dist/providers/index.cjs.map +0 -1
  232. package/dist/providers/index.css +0 -9
  233. package/dist/providers/index.css.map +0 -1
  234. package/dist/providers/index.d.cts +0 -28
  235. package/dist/providers/index.d.ts +0 -28
  236. package/dist/providers/index.js +0 -21
  237. package/dist/providers/index.js.map +0 -1
  238. package/dist/themes-D0qc5JaW.d.cts +0 -67
  239. package/dist/themes-itO4Ht5g.d.ts +0 -67
  240. package/dist/types-B5f6XQ7Q.d.cts +0 -19
  241. package/dist/types-BsHooDbM.d.ts +0 -19
  242. package/dist/types-BuSrRM4p.d.ts +0 -49
  243. package/dist/types-ChOUI9-N.d.cts +0 -545
  244. package/dist/types-ChOUI9-N.d.ts +0 -545
  245. package/dist/types-Dfw9VOKI.d.cts +0 -49
  246. package/dist/utils/index.cjs +0 -44
  247. package/dist/utils/index.cjs.map +0 -1
  248. package/dist/utils/index.d.cts +0 -226
  249. package/dist/utils/index.d.ts +0 -226
  250. package/dist/utils/index.js +0 -44
  251. package/dist/utils/index.js.map +0 -1
  252. package/dist/with-responsive-CNfhzAUu.d.cts +0 -18
  253. package/dist/with-responsive-CNfhzAUu.d.ts +0 -18
@@ -1,421 +0,0 @@
1
- import {
2
- Stack
3
- } from "./chunk-YAFQVVDI.js";
4
- import {
5
- GlobalChartsContext,
6
- GlobalChartsProvider,
7
- useChartId,
8
- useChartRegistration,
9
- useGlobalChartsContext,
10
- useGlobalChartsTheme,
11
- usePrefersReducedMotion
12
- } from "./chunk-2I67QUIV.js";
13
- import {
14
- formatPercentage,
15
- hexToRgba
16
- } from "./chunk-JJIMABHT.js";
17
-
18
- // src/charts/conversion-funnel-chart/conversion-funnel-chart.tsx
19
- import { useTooltip, useTooltipInPortal } from "@visx/tooltip";
20
- import clsx from "clsx";
21
- import { useRef, useMemo, useEffect, useCallback as useCallback2, useContext } from "react";
22
-
23
- // src/charts/conversion-funnel-chart/conversion-funnel-chart.module.scss
24
- var conversion_funnel_chart_module_default = {
25
- "conversionFunnelChart": "a8ccharts-lK-YNK",
26
- "loading": "a8ccharts-DbHKK5",
27
- "main-metric": "a8ccharts-61WPYr",
28
- "main-rate": "a8ccharts-RRRI6x",
29
- "change-indicator": "a8ccharts-661iwx",
30
- "funnel-container": "a8ccharts-Z7EGnW",
31
- "funnel-step": "a8ccharts-VqFY0l",
32
- "blurred": "a8ccharts-7dTRBs",
33
- "step-header": "a8ccharts-2JsQiV",
34
- "step-label": "a8ccharts-6OabC4",
35
- "step-rate": "a8ccharts-9wSZ6n",
36
- "bar-container": "a8ccharts-sSmCTi",
37
- "disabled": "a8ccharts-PLWVAW",
38
- "funnel-bar": "a8ccharts-EzczI-",
39
- "selected": "a8ccharts-wNpZEu",
40
- "funnel-bar--animated": "a8ccharts-68HQJl",
41
- "stretch": "a8ccharts-CmtieZ",
42
- "tooltip-wrapper": "a8ccharts-2TeoCn",
43
- "tooltip-title": "a8ccharts-jkRitH",
44
- "tooltip-content": "a8ccharts-8jgT-3",
45
- "empty-state": "a8ccharts-Ml6MMr"
46
- };
47
-
48
- // src/charts/conversion-funnel-chart/private/use-funnel-selection.ts
49
- import { useCallback, useState } from "react";
50
- var useFunnelSelection = (hideTooltip) => {
51
- const [clickedStep, setClickedStep] = useState(null);
52
- const handleBarClick = useCallback(
53
- (stepId) => {
54
- if (clickedStep === stepId) {
55
- setClickedStep(null);
56
- hideTooltip?.();
57
- } else {
58
- setClickedStep(stepId);
59
- }
60
- },
61
- [clickedStep, hideTooltip]
62
- );
63
- const handleBarKeyDown = useCallback(
64
- (stepId, event) => {
65
- if (event.key === "Enter" || event.key === " ") {
66
- event.preventDefault();
67
- if (clickedStep === stepId) {
68
- setClickedStep(null);
69
- hideTooltip?.();
70
- } else {
71
- setClickedStep(stepId);
72
- }
73
- } else if (event.key === "Escape") {
74
- event.preventDefault();
75
- setClickedStep(null);
76
- hideTooltip?.();
77
- }
78
- },
79
- [clickedStep, hideTooltip]
80
- );
81
- const clearSelection = useCallback(() => {
82
- setClickedStep(null);
83
- hideTooltip?.();
84
- }, [hideTooltip]);
85
- const getStepState = useCallback(
86
- (stepId) => ({
87
- isClicked: clickedStep === stepId,
88
- isBlurred: clickedStep !== null && clickedStep !== stepId
89
- }),
90
- [clickedStep]
91
- );
92
- return {
93
- clickedStep,
94
- handleBarClick,
95
- handleBarKeyDown,
96
- clearSelection,
97
- getStepState
98
- };
99
- };
100
-
101
- // src/charts/conversion-funnel-chart/conversion-funnel-chart.tsx
102
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
103
- var ConversionFunnelChartInternal = ({
104
- mainRate,
105
- changeIndicator,
106
- steps,
107
- loading = false,
108
- animation,
109
- className,
110
- chartId: providedChartId,
111
- height,
112
- style,
113
- renderStepLabel,
114
- renderStepRate,
115
- renderMainMetric,
116
- renderTooltip
117
- }) => {
118
- const chartId = useChartId(providedChartId);
119
- const {
120
- conversionFunnelChart: conversionFunnelChartSettings
121
- } = useGlobalChartsTheme();
122
- const {
123
- getElementStyles
124
- } = useGlobalChartsContext();
125
- const chartRef = useRef(null);
126
- const selectedBarRef = useRef(null);
127
- const {
128
- tooltipData,
129
- tooltipLeft,
130
- tooltipTop,
131
- tooltipOpen,
132
- showTooltip,
133
- hideTooltip
134
- } = useTooltip();
135
- const {
136
- handleBarClick,
137
- handleBarKeyDown,
138
- clearSelection,
139
- getStepState
140
- } = useFunnelSelection(hideTooltip);
141
- const {
142
- containerRef: portalContainerRef,
143
- TooltipInPortal,
144
- containerBounds
145
- } = useTooltipInPortal({
146
- // use TooltipWithBounds for boundary detection
147
- detectBounds: true,
148
- // when tooltip containers are scrolled, this will correctly update the Tooltip position
149
- scroll: true
150
- });
151
- const clearSelectionAndRef = useCallback2(() => {
152
- clearSelection();
153
- selectedBarRef.current = null;
154
- hideTooltip();
155
- }, [clearSelection, hideTooltip]);
156
- const showTooltipAt = useCallback2((step, x, y) => {
157
- showTooltip({
158
- tooltipData: step,
159
- tooltipLeft: x,
160
- tooltipTop: y - 10
161
- });
162
- }, [showTooltip]);
163
- const getMouseTooltipCoords = useCallback2((event) => {
164
- if (containerBounds.width === 0 || containerBounds.height === 0) {
165
- return null;
166
- }
167
- return {
168
- x: event.clientX - containerBounds.left,
169
- y: event.clientY - containerBounds.top
170
- };
171
- }, [containerBounds.width, containerBounds.height, containerBounds.left, containerBounds.top]);
172
- const getKeyboardTooltipCoords = useCallback2((event) => {
173
- if (containerBounds.width === 0 || containerBounds.height === 0) {
174
- return null;
175
- }
176
- const rect = event.currentTarget.getBoundingClientRect();
177
- const x = rect.left + rect.width / 2 - containerBounds.left;
178
- const y = rect.top - containerBounds.top;
179
- return {
180
- x,
181
- y
182
- };
183
- }, [containerBounds.width, containerBounds.height, containerBounds.left, containerBounds.top]);
184
- const handleStepInteraction = useCallback2((step, event, interactionType) => {
185
- selectedBarRef.current = event.currentTarget;
186
- const {
187
- isClicked
188
- } = getStepState(step.id);
189
- if (isClicked) {
190
- if (interactionType === "click") {
191
- handleBarClick(step.id);
192
- } else {
193
- handleBarKeyDown(step.id, event);
194
- }
195
- return;
196
- }
197
- if (interactionType === "click") {
198
- handleBarClick(step.id);
199
- const coords = getMouseTooltipCoords(event);
200
- if (coords) {
201
- showTooltipAt(step, coords.x, coords.y);
202
- }
203
- } else {
204
- handleBarKeyDown(step.id, event);
205
- const coords = getKeyboardTooltipCoords(event);
206
- if (coords) {
207
- showTooltipAt(step, coords.x, coords.y);
208
- }
209
- }
210
- }, [getStepState, handleBarClick, handleBarKeyDown, showTooltipAt, getMouseTooltipCoords, getKeyboardTooltipCoords]);
211
- const stepHandlers = useMemo(() => {
212
- const handlers = /* @__PURE__ */ new Map();
213
- steps.forEach((step) => {
214
- const onClick = (event) => {
215
- event.stopPropagation();
216
- handleStepInteraction(step, event, "click");
217
- };
218
- const onKeyDown = (event) => {
219
- if (event.key === "Enter" || event.key === " ") {
220
- handleStepInteraction(step, event, "keyboard");
221
- } else {
222
- selectedBarRef.current = event.currentTarget;
223
- handleBarKeyDown(step.id, event);
224
- }
225
- };
226
- handlers.set(step.id, {
227
- onClick,
228
- onKeyDown
229
- });
230
- });
231
- return handlers;
232
- }, [steps, handleStepInteraction, handleBarKeyDown]);
233
- useEffect(() => {
234
- const handleDocumentClick = (event) => {
235
- if (selectedBarRef.current && !selectedBarRef.current.contains(event.target)) {
236
- clearSelectionAndRef();
237
- }
238
- };
239
- document.addEventListener("mousedown", handleDocumentClick);
240
- return () => {
241
- document.removeEventListener("mousedown", handleDocumentClick);
242
- };
243
- }, [clearSelectionAndRef]);
244
- const resolvedHeight = height ?? style?.height ?? "100%";
245
- const {
246
- primaryColor,
247
- backgroundColor,
248
- positiveChangeColor,
249
- negativeChangeColor
250
- } = conversionFunnelChartSettings;
251
- const {
252
- color: barColor
253
- } = getElementStyles ? getElementStyles({
254
- index: 0,
255
- overrideColor: primaryColor
256
- }) : {
257
- color: primaryColor || "#000000"
258
- };
259
- const isPositiveChange = changeIndicator?.startsWith("+");
260
- const changeColor = isPositiveChange ? positiveChangeColor : negativeChangeColor;
261
- const barBackgroundColor = backgroundColor || hexToRgba(barColor, 0.08) || "rgba(0, 0, 0, 0.08)";
262
- const renderDefaultMainMetric = () => /* @__PURE__ */ _jsxs(_Fragment, {
263
- children: [/* @__PURE__ */ _jsx("span", {
264
- className: conversion_funnel_chart_module_default["main-rate"],
265
- children: formatPercentage(mainRate)
266
- }), changeIndicator && /* @__PURE__ */ _jsx("span", {
267
- className: conversion_funnel_chart_module_default["change-indicator"],
268
- style: {
269
- color: changeColor
270
- },
271
- children: changeIndicator
272
- })]
273
- });
274
- const renderDefaultTooltip = (step) => /* @__PURE__ */ _jsxs(_Fragment, {
275
- children: [/* @__PURE__ */ _jsx("div", {
276
- className: conversion_funnel_chart_module_default["tooltip-title"],
277
- children: step.label
278
- }), /* @__PURE__ */ _jsxs("div", {
279
- className: conversion_funnel_chart_module_default["tooltip-content"],
280
- children: [formatPercentage(step.rate), ` \u2022 ${step.count ?? "no"} items`]
281
- })]
282
- });
283
- const isDataValid = Boolean(steps && steps.length > 0);
284
- const chartMetadata = useMemo(() => ({
285
- mainRate,
286
- changeIndicator,
287
- stepsCount: steps?.length || 0
288
- }), [mainRate, changeIndicator, steps?.length]);
289
- useChartRegistration({
290
- chartId,
291
- legendItems: [],
292
- chartType: "conversion-funnel",
293
- isDataValid,
294
- metadata: chartMetadata
295
- });
296
- const prefersReducedMotion = usePrefersReducedMotion();
297
- if (!isDataValid) {
298
- return /* @__PURE__ */ _jsx(Stack, {
299
- direction: "column",
300
- className: clsx(conversion_funnel_chart_module_default.conversionFunnelChart, loading && conversion_funnel_chart_module_default.loading, className),
301
- style: {
302
- ...style,
303
- height: resolvedHeight
304
- },
305
- children: /* @__PURE__ */ _jsx("div", {
306
- className: conversion_funnel_chart_module_default["empty-state"],
307
- children: loading ? "Loading..." : "No data available"
308
- })
309
- });
310
- }
311
- const maxRate = Math.max(...steps.map((step) => step.rate));
312
- return /* @__PURE__ */ _jsxs(_Fragment, {
313
- children: [/* @__PURE__ */ _jsxs(Stack, {
314
- direction: "column",
315
- ref: (node) => {
316
- portalContainerRef(node);
317
- chartRef.current = node;
318
- },
319
- className: clsx(conversion_funnel_chart_module_default.conversionFunnelChart, loading && conversion_funnel_chart_module_default.loading, className),
320
- style: {
321
- ...style,
322
- height: resolvedHeight
323
- },
324
- children: [renderMainMetric ? renderMainMetric({
325
- mainRate,
326
- changeIndicator,
327
- className: conversion_funnel_chart_module_default["main-metric"],
328
- changeColor
329
- }) : /* @__PURE__ */ _jsx("div", {
330
- className: conversion_funnel_chart_module_default["main-metric"],
331
- children: renderDefaultMainMetric()
332
- }), /* @__PURE__ */ _jsx("div", {
333
- className: conversion_funnel_chart_module_default["funnel-container"],
334
- children: steps.map((step, index) => {
335
- const barHeight = step.rate / maxRate * 100;
336
- const {
337
- isBlurred
338
- } = getStepState(step.id);
339
- return /* @__PURE__ */ _jsxs("div", {
340
- className: clsx(conversion_funnel_chart_module_default["funnel-step"], isBlurred && conversion_funnel_chart_module_default.blurred),
341
- children: [/* @__PURE__ */ _jsxs("div", {
342
- className: conversion_funnel_chart_module_default["step-header"],
343
- children: [renderStepLabel ? renderStepLabel({
344
- step,
345
- index,
346
- className: conversion_funnel_chart_module_default["step-label"]
347
- }) : /* @__PURE__ */ _jsx("span", {
348
- className: conversion_funnel_chart_module_default["step-label"],
349
- children: step.label
350
- }), renderStepRate ? renderStepRate({
351
- step,
352
- index,
353
- className: conversion_funnel_chart_module_default["step-rate"]
354
- }) : /* @__PURE__ */ _jsx("span", {
355
- className: conversion_funnel_chart_module_default["step-rate"],
356
- children: formatPercentage(step.rate)
357
- })]
358
- }), /* @__PURE__ */ _jsx("div", {
359
- className: clsx(conversion_funnel_chart_module_default["bar-container"], isBlurred && conversion_funnel_chart_module_default.disabled),
360
- onClick: stepHandlers.get(step.id)?.onClick,
361
- onKeyDown: stepHandlers.get(step.id)?.onKeyDown,
362
- role: "button",
363
- tabIndex: isBlurred ? -1 : 0,
364
- "aria-label": step.label,
365
- style: {
366
- backgroundColor: barBackgroundColor
367
- },
368
- children: /* @__PURE__ */ _jsx("div", {
369
- className: clsx(conversion_funnel_chart_module_default["funnel-bar"], {
370
- [conversion_funnel_chart_module_default["funnel-bar--animated"]]: animation && !loading && !prefersReducedMotion
371
- }),
372
- style: {
373
- height: `${barHeight}%`,
374
- backgroundColor: barColor
375
- }
376
- })
377
- })]
378
- }, step.id);
379
- })
380
- })]
381
- }), tooltipOpen && tooltipData && (() => {
382
- const tooltipContent = renderTooltip ? renderTooltip({
383
- step: tooltipData,
384
- index: steps.findIndex((s) => s.id === tooltipData.id),
385
- top: tooltipTop,
386
- left: tooltipLeft,
387
- className: conversion_funnel_chart_module_default["tooltip-wrapper"]
388
- }) : renderDefaultTooltip(tooltipData);
389
- if (!tooltipContent) return null;
390
- return /* @__PURE__ */ _jsx(
391
- TooltipInPortal,
392
- {
393
- top: tooltipTop,
394
- left: tooltipLeft,
395
- className: conversion_funnel_chart_module_default["tooltip-wrapper"],
396
- children: tooltipContent
397
- },
398
- Math.random()
399
- );
400
- })()]
401
- });
402
- };
403
- var ConversionFunnelChartWithProvider = (props) => {
404
- const existingContext = useContext(GlobalChartsContext);
405
- if (existingContext) {
406
- return /* @__PURE__ */ _jsx(ConversionFunnelChartInternal, {
407
- ...props
408
- });
409
- }
410
- return /* @__PURE__ */ _jsx(GlobalChartsProvider, {
411
- children: /* @__PURE__ */ _jsx(ConversionFunnelChartInternal, {
412
- ...props
413
- })
414
- });
415
- };
416
- ConversionFunnelChartWithProvider.displayName = "ConversionFunnelChart";
417
-
418
- export {
419
- ConversionFunnelChartWithProvider
420
- };
421
- //# sourceMappingURL=chunk-KJHWXOCZ.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/charts/conversion-funnel-chart/conversion-funnel-chart.tsx","../src/charts/conversion-funnel-chart/conversion-funnel-chart.module.scss","../src/charts/conversion-funnel-chart/private/use-funnel-selection.ts"],"sourcesContent":["import { useTooltip, useTooltipInPortal } from '@visx/tooltip';\nimport { Stack } from '@wordpress/ui';\nimport clsx from 'clsx';\nimport { useRef, useMemo, useEffect, useCallback, useContext } from 'react';\nimport { usePrefersReducedMotion } from '../../hooks';\nimport { GlobalChartsProvider, GlobalChartsContext, useChartId, useChartRegistration, useGlobalChartsTheme, useGlobalChartsContext } from '../../providers';\nimport { formatPercentage, hexToRgba } from '../../utils';\nimport styles from './conversion-funnel-chart.module.scss';\nimport { useFunnelSelection } from './private';\nimport { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from \"react/jsx-runtime\";\n/**\n * Internal ConversionFunnelChart component with chart registration\n *\n * @param props - Component props\n * @param props.chartId - Optional unique identifier for the chart\n * @param props.mainRate - Main conversion rate to highlight\n * @param props.changeIndicator - Change indicator (e.g., +2%, -1.5%)\n * @param props.steps - Array of funnel steps\n * @param props.loading - Whether the chart is in loading state\n * @param props.animation - Whether to show chart animation on initial render or not\n * @param props.className - Additional CSS class name\n * @param props.height - Height of the chart container. Falls back to style.height if set, otherwise defaults to \"100%\".\n * @param props.style - Custom styling\n * @param props.renderStepLabel - Custom render function for step labels\n * @param props.renderStepRate - Custom render function for step rates\n * @param props.renderMainMetric - Custom render function for the entire main metric section\n * @param props.renderTooltip - Custom render function for tooltip content\n * @return JSX element representing the conversion funnel chart\n */\nconst ConversionFunnelChartInternal = ({\n mainRate,\n changeIndicator,\n steps,\n loading = false,\n animation,\n className,\n chartId: providedChartId,\n height,\n style,\n renderStepLabel,\n renderStepRate,\n renderMainMetric,\n renderTooltip\n}) => {\n const chartId = useChartId(providedChartId);\n const {\n conversionFunnelChart: conversionFunnelChartSettings\n } = useGlobalChartsTheme();\n const {\n getElementStyles\n } = useGlobalChartsContext();\n const chartRef = useRef(null);\n const selectedBarRef = useRef(null);\n\n // Use @visx/tooltip hooks for tooltip positioning\n const {\n tooltipData,\n tooltipLeft,\n tooltipTop,\n tooltipOpen,\n showTooltip,\n hideTooltip\n } = useTooltip();\n\n // Use custom hook for selection management\n const {\n handleBarClick,\n handleBarKeyDown,\n clearSelection,\n getStepState\n } = useFunnelSelection(hideTooltip);\n const {\n containerRef: portalContainerRef,\n TooltipInPortal,\n containerBounds\n } = useTooltipInPortal({\n // use TooltipWithBounds for boundary detection\n detectBounds: true,\n // when tooltip containers are scrolled, this will correctly update the Tooltip position\n scroll: true\n });\n\n // Wrapper to clear selectedBarRef after clearing selection\n const clearSelectionAndRef = useCallback(() => {\n clearSelection();\n selectedBarRef.current = null;\n hideTooltip();\n }, [clearSelection, hideTooltip]);\n\n // Helper function to show tooltip at specific coordinates\n const showTooltipAt = useCallback((step, x, y) => {\n showTooltip({\n tooltipData: step,\n tooltipLeft: x,\n tooltipTop: y - 10\n });\n }, [showTooltip]);\n\n // Helper function to get tooltip coordinates for mouse events\n // Use clientX/Y and subtract containerBounds to cancel out any stale offset.\n // TooltipInPortal calculates: tooltipLeft + containerBounds.left + scrollX\n // By passing (clientX - containerBounds.left), we get correct page coordinates\n // regardless of whether bounds are stale (e.g., after dashboard customization).\n const getMouseTooltipCoords = useCallback(event => {\n // Don't return coords until container bounds are measured\n if (containerBounds.width === 0 || containerBounds.height === 0) {\n return null;\n }\n return {\n x: event.clientX - containerBounds.left,\n y: event.clientY - containerBounds.top\n };\n }, [containerBounds.width, containerBounds.height, containerBounds.left, containerBounds.top]);\n\n // Helper function to get tooltip coordinates for keyboard events\n // Use fresh getBoundingClientRect() and subtract containerBounds to cancel out stale offset.\n const getKeyboardTooltipCoords = useCallback(event => {\n // Don't return coords until container bounds are measured\n if (containerBounds.width === 0 || containerBounds.height === 0) {\n return null;\n }\n const rect = event.currentTarget.getBoundingClientRect();\n // Calculate center of element in viewport coordinates, then subtract containerBounds\n const x = rect.left + rect.width / 2 - containerBounds.left;\n const y = rect.top - containerBounds.top;\n return {\n x,\n y\n };\n }, [containerBounds.width, containerBounds.height, containerBounds.left, containerBounds.top]);\n\n // Helper function to handle step interaction (both click and keyboard)\n const handleStepInteraction = useCallback((step, event, interactionType) => {\n // Store reference to the interacted element\n selectedBarRef.current = event.currentTarget;\n\n // Check if deselecting the same step\n const {\n isClicked\n } = getStepState(step.id);\n if (isClicked) {\n // Deselecting - clear selection (tooltip will be hidden by hook)\n if (interactionType === 'click') {\n handleBarClick(step.id);\n } else {\n handleBarKeyDown(step.id, event);\n }\n return;\n }\n\n // Selecting - handle selection and show tooltip\n if (interactionType === 'click') {\n handleBarClick(step.id);\n const coords = getMouseTooltipCoords(event);\n if (coords) {\n showTooltipAt(step, coords.x, coords.y);\n }\n } else {\n handleBarKeyDown(step.id, event);\n const coords = getKeyboardTooltipCoords(event);\n if (coords) {\n showTooltipAt(step, coords.x, coords.y);\n }\n }\n }, [getStepState, handleBarClick, handleBarKeyDown, showTooltipAt, getMouseTooltipCoords, getKeyboardTooltipCoords]);\n\n // Create handler factories to avoid arrow functions in JSX\n const stepHandlers = useMemo(() => {\n const handlers = new Map();\n steps.forEach(step => {\n const onClick = event => {\n event.stopPropagation();\n handleStepInteraction(step, event, 'click');\n };\n const onKeyDown = event => {\n if (event.key === 'Enter' || event.key === ' ') {\n handleStepInteraction(step, event, 'keyboard');\n } else {\n // For other keys (like Escape), just handle the selection\n selectedBarRef.current = event.currentTarget;\n handleBarKeyDown(step.id, event);\n }\n };\n handlers.set(step.id, {\n onClick,\n onKeyDown\n });\n });\n return handlers;\n }, [steps, handleStepInteraction, handleBarKeyDown]);\n\n // Handle document-level click to clear selection when clicking outside selected bar\n useEffect(() => {\n const handleDocumentClick = event => {\n // Only clear selection if there's an active selection and click is outside the selected bar\n if (selectedBarRef.current && !selectedBarRef.current.contains(event.target)) {\n clearSelectionAndRef();\n }\n };\n document.addEventListener('mousedown', handleDocumentClick);\n return () => {\n document.removeEventListener('mousedown', handleDocumentClick);\n };\n }, [clearSelectionAndRef]);\n\n // Resolve height: explicit height prop > style.height > default 100%\n const resolvedHeight = height ?? style?.height ?? '100%';\n\n // Get component settings from theme with fallbacks\n const {\n primaryColor,\n backgroundColor,\n positiveChangeColor,\n negativeChangeColor\n } = conversionFunnelChartSettings;\n\n // Resolve bar color using getElementStyles with primaryColor as override\n const {\n color: barColor\n } = getElementStyles ? getElementStyles({\n index: 0,\n overrideColor: primaryColor\n }) : {\n color: primaryColor || '#000000'\n };\n\n // Determine change indicator color\n const isPositiveChange = changeIndicator?.startsWith('+');\n const changeColor = isPositiveChange ? positiveChangeColor : negativeChangeColor;\n\n // Create light background version of primary color if not set\n const barBackgroundColor = backgroundColor || hexToRgba(barColor, 0.08) || 'rgba(0, 0, 0, 0.08)';\n\n // Default main metric rendering function\n const renderDefaultMainMetric = () => /*#__PURE__*/_jsxs(_Fragment, {\n children: [/*#__PURE__*/_jsx(\"span\", {\n className: styles['main-rate'],\n children: formatPercentage(mainRate)\n }), changeIndicator && /*#__PURE__*/_jsx(\"span\", {\n className: styles['change-indicator'],\n style: {\n color: changeColor\n },\n children: changeIndicator\n })]\n });\n\n // Default tooltip rendering function\n const renderDefaultTooltip = step => /*#__PURE__*/_jsxs(_Fragment, {\n children: [/*#__PURE__*/_jsx(\"div\", {\n className: styles['tooltip-title'],\n children: step.label\n }), /*#__PURE__*/_jsxs(\"div\", {\n className: styles['tooltip-content'],\n children: [formatPercentage(step.rate), ` • ${step.count ?? 'no'} items`]\n })]\n });\n\n // Validate data\n const isDataValid = Boolean(steps && steps.length > 0);\n\n // Memoize metadata to prevent unnecessary re-registration\n const chartMetadata = useMemo(() => ({\n mainRate,\n changeIndicator,\n stepsCount: steps?.length || 0\n }), [mainRate, changeIndicator, steps?.length]);\n useChartRegistration({\n chartId,\n legendItems: [],\n chartType: 'conversion-funnel',\n isDataValid,\n metadata: chartMetadata\n });\n const prefersReducedMotion = usePrefersReducedMotion();\n\n // Handle empty or undefined data\n if (!isDataValid) {\n return /*#__PURE__*/_jsx(Stack, {\n direction: \"column\",\n className: clsx(styles.conversionFunnelChart, loading && styles.loading, className),\n style: {\n ...style,\n height: resolvedHeight\n },\n children: /*#__PURE__*/_jsx(\"div\", {\n className: styles['empty-state'],\n children: loading ? 'Loading...' : 'No data available'\n })\n });\n }\n\n // Calculate bar heights relative to the maximum (first step)\n const maxRate = Math.max(...steps.map(step => step.rate));\n return /*#__PURE__*/_jsxs(_Fragment, {\n children: [/*#__PURE__*/_jsxs(Stack, {\n direction: \"column\",\n ref: node => {\n // Set containerRef for @visx coordinate system\n portalContainerRef(node);\n chartRef.current = node;\n },\n className: clsx(styles.conversionFunnelChart, loading && styles.loading, className),\n style: {\n ...style,\n height: resolvedHeight\n },\n children: [renderMainMetric ? renderMainMetric({\n mainRate,\n changeIndicator,\n className: styles['main-metric'],\n changeColor\n }) : /*#__PURE__*/_jsx(\"div\", {\n className: styles['main-metric'],\n children: renderDefaultMainMetric()\n }), /*#__PURE__*/_jsx(\"div\", {\n className: styles['funnel-container'],\n children: steps.map((step, index) => {\n const barHeight = step.rate / maxRate * 100;\n const {\n isBlurred\n } = getStepState(step.id);\n return /*#__PURE__*/_jsxs(\"div\", {\n className: clsx(styles['funnel-step'], isBlurred && styles.blurred),\n children: [/*#__PURE__*/_jsxs(\"div\", {\n className: styles['step-header'],\n children: [renderStepLabel ? renderStepLabel({\n step,\n index,\n className: styles['step-label']\n }) : /*#__PURE__*/_jsx(\"span\", {\n className: styles['step-label'],\n children: step.label\n }), renderStepRate ? renderStepRate({\n step,\n index,\n className: styles['step-rate']\n }) : /*#__PURE__*/_jsx(\"span\", {\n className: styles['step-rate'],\n children: formatPercentage(step.rate)\n })]\n }), /*#__PURE__*/_jsx(\"div\", {\n className: clsx(styles['bar-container'], isBlurred && styles.disabled),\n onClick: stepHandlers.get(step.id)?.onClick,\n onKeyDown: stepHandlers.get(step.id)?.onKeyDown,\n role: \"button\",\n tabIndex: isBlurred ? -1 : 0,\n \"aria-label\": step.label,\n style: {\n backgroundColor: barBackgroundColor\n },\n children: /*#__PURE__*/_jsx(\"div\", {\n className: clsx(styles['funnel-bar'], {\n [styles['funnel-bar--animated']]: animation && !loading && !prefersReducedMotion\n }),\n style: {\n height: `${barHeight}%`,\n backgroundColor: barColor\n }\n })\n })]\n }, step.id);\n })\n })]\n }), tooltipOpen && tooltipData && (() => {\n const tooltipContent = renderTooltip ? renderTooltip({\n step: tooltipData,\n index: steps.findIndex(s => s.id === tooltipData.id),\n top: tooltipTop,\n left: tooltipLeft,\n className: styles['tooltip-wrapper']\n }) : renderDefaultTooltip(tooltipData);\n\n // Don't render tooltip if renderTooltip returns falsy\n if (!tooltipContent) return null;\n return /*#__PURE__*/_jsx(TooltipInPortal\n // set this to random so it correctly updates with parent bounds\n , {\n top: tooltipTop,\n left: tooltipLeft,\n className: styles['tooltip-wrapper'],\n children: tooltipContent\n }, Math.random());\n })()]\n });\n};\n\n/**\n * ConversionFunnelChart component with provider wrapper\n *\n * @param props - Component props\n * @return JSX element representing the conversion funnel chart\n */\nconst ConversionFunnelChartWithProvider = props => {\n const existingContext = useContext(GlobalChartsContext);\n\n // If we're already in a GlobalChartsProvider context, don't create a new one\n if (existingContext) {\n return /*#__PURE__*/_jsx(ConversionFunnelChartInternal, {\n ...props\n });\n }\n\n // Otherwise, create our own GlobalChartsProvider\n return /*#__PURE__*/_jsx(GlobalChartsProvider, {\n children: /*#__PURE__*/_jsx(ConversionFunnelChartInternal, {\n ...props\n })\n });\n};\nConversionFunnelChartWithProvider.displayName = 'ConversionFunnelChart';\nexport { ConversionFunnelChartWithProvider as default };","import 'css-chunk:src/charts/conversion-funnel-chart/conversion-funnel-chart.module.scss';export default {\n \"conversionFunnelChart\": \"a8ccharts-lK-YNK\",\n \"loading\": \"a8ccharts-DbHKK5\",\n \"main-metric\": \"a8ccharts-61WPYr\",\n \"main-rate\": \"a8ccharts-RRRI6x\",\n \"change-indicator\": \"a8ccharts-661iwx\",\n \"funnel-container\": \"a8ccharts-Z7EGnW\",\n \"funnel-step\": \"a8ccharts-VqFY0l\",\n \"blurred\": \"a8ccharts-7dTRBs\",\n \"step-header\": \"a8ccharts-2JsQiV\",\n \"step-label\": \"a8ccharts-6OabC4\",\n \"step-rate\": \"a8ccharts-9wSZ6n\",\n \"bar-container\": \"a8ccharts-sSmCTi\",\n \"disabled\": \"a8ccharts-PLWVAW\",\n \"funnel-bar\": \"a8ccharts-EzczI-\",\n \"selected\": \"a8ccharts-wNpZEu\",\n \"funnel-bar--animated\": \"a8ccharts-68HQJl\",\n \"stretch\": \"a8ccharts-CmtieZ\",\n \"tooltip-wrapper\": \"a8ccharts-2TeoCn\",\n \"tooltip-title\": \"a8ccharts-jkRitH\",\n \"tooltip-content\": \"a8ccharts-8jgT-3\",\n \"empty-state\": \"a8ccharts-Ml6MMr\"\n};","import { useCallback, useState } from 'react';\n\n/**\n * Custom hook to manage funnel bar selection state and interactions\n * @param hideTooltip - Function to hide tooltip when selection is cleared\n * @return Object containing selection state and event handlers\n */\nexport const useFunnelSelection = ( hideTooltip?: () => void ) => {\n\tconst [ clickedStep, setClickedStep ] = useState< string | null >( null );\n\n\t// Handle bar click\n\tconst handleBarClick = useCallback(\n\t\t( stepId: string ) => {\n\t\t\tif ( clickedStep === stepId ) {\n\t\t\t\t// If clicking the same step, deselect it\n\t\t\t\tsetClickedStep( null );\n\t\t\t\thideTooltip?.();\n\t\t\t} else {\n\t\t\t\t// Otherwise, select this step\n\t\t\t\tsetClickedStep( stepId );\n\t\t\t}\n\t\t},\n\t\t[ clickedStep, hideTooltip ]\n\t);\n\n\t// Handle bar keydown\n\tconst handleBarKeyDown = useCallback(\n\t\t( stepId: string, event: React.KeyboardEvent ) => {\n\t\t\tif ( event.key === 'Enter' || event.key === ' ' ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tif ( clickedStep === stepId ) {\n\t\t\t\t\tsetClickedStep( null );\n\t\t\t\t\thideTooltip?.();\n\t\t\t\t} else {\n\t\t\t\t\tsetClickedStep( stepId );\n\t\t\t\t}\n\t\t\t} else if ( event.key === 'Escape' ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tsetClickedStep( null );\n\t\t\t\thideTooltip?.();\n\t\t\t}\n\t\t},\n\t\t[ clickedStep, hideTooltip ]\n\t);\n\n\t// Clear selection (for chart-level click)\n\tconst clearSelection = useCallback( () => {\n\t\tsetClickedStep( null );\n\t\thideTooltip?.();\n\t}, [ hideTooltip ] );\n\n\t// Get step state helpers\n\tconst getStepState = useCallback(\n\t\t( stepId: string ) => ( {\n\t\t\tisClicked: clickedStep === stepId,\n\t\t\tisBlurred: clickedStep !== null && clickedStep !== stepId,\n\t\t} ),\n\t\t[ clickedStep ]\n\t);\n\n\treturn {\n\t\tclickedStep,\n\t\thandleBarClick,\n\t\thandleBarKeyDown,\n\t\tclearSelection,\n\t\tgetStepState,\n\t};\n};\n"],"mappings":"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","names":["useCallback","useCallback"]}
@@ -1,91 +0,0 @@
1
- import {
2
- Legend
3
- } from "./chunk-WTQYGUNF.js";
4
-
5
- // src/charts/private/chart-composition/chart-svg.tsx
6
- import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
7
- var ChartSVG = ({
8
- children
9
- }) => {
10
- return /* @__PURE__ */ _jsx(_Fragment, {
11
- children
12
- });
13
- };
14
- ChartSVG.displayName = "Chart.SVG";
15
-
16
- // src/charts/private/chart-composition/chart-html.tsx
17
- import { Fragment as _Fragment2, jsx as _jsx2 } from "react/jsx-runtime";
18
- var ChartHTML = ({
19
- children
20
- }) => {
21
- return /* @__PURE__ */ _jsx2(_Fragment2, {
22
- children
23
- });
24
- };
25
- ChartHTML.displayName = "Chart.HTML";
26
-
27
- // src/charts/private/chart-composition/render-legend-slot.ts
28
- import { createElement, Fragment } from "react";
29
- function renderLegendSlot(legendChildren, position) {
30
- return legendChildren.filter((l) => l.position === position).map(
31
- (l, i) => createElement(Fragment, { key: `legend-${position}-${i}` }, l.element)
32
- );
33
- }
34
-
35
- // src/charts/private/chart-composition/use-chart-children.ts
36
- import { Group } from "@visx/group";
37
- import { useMemo, Children, isValidElement } from "react";
38
- function useChartChildren(children, chartType) {
39
- return useMemo(() => {
40
- const svg = [];
41
- const html = [];
42
- const legend = [];
43
- const other = [];
44
- const nonLegend = [];
45
- Children.forEach(children, (child) => {
46
- if (isValidElement(child)) {
47
- if (child.type === Legend) {
48
- const rawPosition = child.props?.position;
49
- const position = rawPosition === "top" || rawPosition === "bottom" ? rawPosition : "bottom";
50
- legend.push({ element: child, position });
51
- return;
52
- }
53
- const childType = child.type;
54
- const displayName = childType?.displayName;
55
- if (displayName === `${chartType}.SVG` || displayName === "Chart.SVG") {
56
- if (child.props?.children) {
57
- Children.forEach(child.props.children, (svgChild) => {
58
- svg.push(svgChild);
59
- });
60
- }
61
- } else if (displayName === `${chartType}.HTML` || displayName === "Chart.HTML") {
62
- if (child.props?.children) {
63
- Children.forEach(child.props.children, (htmlChild) => {
64
- html.push(htmlChild);
65
- });
66
- }
67
- } else if (child.type === Group) {
68
- svg.push(child);
69
- } else {
70
- other.push(child);
71
- }
72
- }
73
- nonLegend.push(child);
74
- });
75
- return {
76
- svgChildren: svg,
77
- htmlChildren: html,
78
- legendChildren: legend,
79
- otherChildren: other,
80
- nonLegendChildren: nonLegend
81
- };
82
- }, [children, chartType]);
83
- }
84
-
85
- export {
86
- ChartSVG,
87
- ChartHTML,
88
- renderLegendSlot,
89
- useChartChildren
90
- };
91
- //# sourceMappingURL=chunk-KRWGSOJ2.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/charts/private/chart-composition/chart-svg.tsx","../src/charts/private/chart-composition/chart-html.tsx","../src/charts/private/chart-composition/render-legend-slot.ts","../src/charts/private/chart-composition/use-chart-children.ts"],"sourcesContent":["import { Fragment as _Fragment, jsx as _jsx } from \"react/jsx-runtime\";\n/**\n * Compound component for SVG children in charts.\n * This component serves as a marker for SVG content that should be rendered\n * inside the chart's SVG element. The actual rendering is handled by the parent chart.\n *\n * @param {PropsWithChildren} props - Component props\n * @param {ReactNode} props.children - Child elements to render inside the SVG\n * @return {JSX.Element} The children wrapped in a fragment\n */\nexport const ChartSVG = ({\n children\n}) => {\n // This component doesn't render directly - its children are extracted by the parent chart\n // We just return the children as-is\n return /*#__PURE__*/_jsx(_Fragment, {\n children: children\n });\n};\n\n// Set displayName for better debugging and type checking\nChartSVG.displayName = 'Chart.SVG';","import { Fragment as _Fragment, jsx as _jsx } from \"react/jsx-runtime\";\n/**\n * Compound component for HTML children in charts.\n * This component serves as a marker for HTML content that should be rendered\n * outside the chart's SVG element. The actual rendering is handled by the parent chart.\n *\n * @param {PropsWithChildren} props - Component props\n * @param {ReactNode} props.children - Child elements to render outside the SVG\n * @return {JSX.Element} The children wrapped in a fragment\n */\nexport const ChartHTML = ({\n children\n}) => {\n // This component doesn't render directly - its children are extracted by the parent chart\n // We just return the children as-is\n return /*#__PURE__*/_jsx(_Fragment, {\n children: children\n });\n};\n\n// Set displayName for better debugging and type checking\nChartHTML.displayName = 'Chart.HTML';","import { createElement, Fragment } from 'react';\nimport type { LegendChild } from './use-chart-children';\nimport type { LegendPosition } from '../../../types';\nimport type { ReactNode } from 'react';\n\n/**\n * Renders legend children filtered by position slot.\n *\n * @param {LegendChild[]} legendChildren - The legend children to filter and render\n * @param {LegendPosition} position - The position slot to render\n * @return {ReactNode[]} Array of legend elements for the given position\n */\nexport function renderLegendSlot(\n\tlegendChildren: LegendChild[],\n\tposition: LegendPosition\n): ReactNode[] {\n\treturn legendChildren\n\t\t.filter( l => l.position === position )\n\t\t.map( ( l, i ) =>\n\t\t\tcreateElement( Fragment, { key: `legend-${ position }-${ i }` }, l.element )\n\t\t);\n}\n","import { Group } from '@visx/group';\nimport { useMemo, Children, isValidElement } from 'react';\nimport { Legend } from '../../../components/legend';\nimport type { LegendPosition } from '../../../types';\nimport type { ReactElement, ReactNode } from 'react';\n\nexport type LegendChild = {\n\telement: ReactElement;\n\tposition: LegendPosition;\n};\n\ninterface ChartChildren {\n\tsvgChildren: ReactNode[];\n\thtmlChildren: ReactNode[];\n\tlegendChildren: LegendChild[];\n\totherChildren: ReactNode[];\n\t/** All children except Legend, in original order. */\n\tnonLegendChildren: ReactNode[];\n}\n\n/**\n * Custom hook to process and categorize chart children for composition API.\n * Extracts children from compound components (Chart.SVG, Chart.HTML) and\n * maintains backward compatibility with legacy Group components.\n *\n * @param {ReactNode} children - The children prop from the chart component\n * @param {string} chartType - The type of chart (e.g., 'PieChart', 'BarChart')\n * @return {ChartChildren} Categorized children for rendering\n */\nexport function useChartChildren( children: ReactNode, chartType: string ): ChartChildren {\n\treturn useMemo( () => {\n\t\tconst svg: ReactNode[] = [];\n\t\tconst html: ReactNode[] = [];\n\t\tconst legend: LegendChild[] = [];\n\t\tconst other: ReactNode[] = [];\n\t\tconst nonLegend: ReactNode[] = [];\n\n\t\tChildren.forEach( children, child => {\n\t\t\tif ( isValidElement( child ) ) {\n\t\t\t\t// Extract Legend children for position-based slot rendering\n\t\t\t\tif ( child.type === Legend ) {\n\t\t\t\t\tconst rawPosition = child.props?.position;\n\t\t\t\t\tconst position =\n\t\t\t\t\t\trawPosition === 'top' || rawPosition === 'bottom' ? rawPosition : 'bottom';\n\n\t\t\t\t\tlegend.push( { element: child as ReactElement, position } );\n\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Check displayName for compound components\n\t\t\t\tconst childType = child.type as { displayName?: string };\n\t\t\t\tconst displayName = childType?.displayName;\n\n\t\t\t\t// Handle chart-specific compound components (e.g., PieChart.SVG)\n\t\t\t\tif ( displayName === `${ chartType }.SVG` || displayName === 'Chart.SVG' ) {\n\t\t\t\t\t// Extract children from Chart.SVG with safety checks\n\t\t\t\t\tif ( child.props?.children ) {\n\t\t\t\t\t\tChildren.forEach( child.props.children, svgChild => {\n\t\t\t\t\t\t\tsvg.push( svgChild );\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\t\t\t\t} else if ( displayName === `${ chartType }.HTML` || displayName === 'Chart.HTML' ) {\n\t\t\t\t\t// Extract children from Chart.HTML with safety checks\n\t\t\t\t\tif ( child.props?.children ) {\n\t\t\t\t\t\tChildren.forEach( child.props.children, htmlChild => {\n\t\t\t\t\t\t\thtml.push( htmlChild );\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\t\t\t\t} else if ( child.type === Group ) {\n\t\t\t\t\t// Legacy support: still check for Group type for backward compatibility\n\t\t\t\t\tsvg.push( child );\n\t\t\t\t} else {\n\t\t\t\t\tother.push( child );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Preserve original order of all non-Legend children\n\t\t\tnonLegend.push( child );\n\t\t} );\n\n\t\treturn {\n\t\t\tsvgChildren: svg,\n\t\t\thtmlChildren: html,\n\t\t\tlegendChildren: legend,\n\t\t\totherChildren: other,\n\t\t\tnonLegendChildren: nonLegend,\n\t\t};\n\t}, [ children, chartType ] );\n}\n"],"mappings":";;;;;AAAA,SAAS,YAAY,WAAW,OAAO,YAAY;AAU5C,IAAM,WAAW,CAAC;AAAA,EACvB;AACF,MAAM;AAGJ,SAAoB,qBAAK,WAAW;AAAA,IAClC;AAAA,EACF,CAAC;AACH;AAGA,SAAS,cAAc;;;ACrBvB,SAAS,YAAYA,YAAW,OAAOC,aAAY;AAU5C,IAAM,YAAY,CAAC;AAAA,EACxB;AACF,MAAM;AAGJ,SAAoB,gBAAAA,MAAKD,YAAW;AAAA,IAClC;AAAA,EACF,CAAC;AACH;AAGA,UAAU,cAAc;;;ACrBxB,SAAS,eAAe,gBAAgB;AAYjC,SAAS,iBACf,gBACA,UACc;AACd,SAAO,eACL,OAAQ,OAAK,EAAE,aAAa,QAAS,EACrC;AAAA,IAAK,CAAE,GAAG,MACV,cAAe,UAAU,EAAE,KAAK,UAAW,QAAS,IAAK,CAAE,GAAG,GAAG,EAAE,OAAQ;AAAA,EAC5E;AACF;;;ACrBA,SAAS,aAAa;AACtB,SAAS,SAAS,UAAU,sBAAsB;AA4B3C,SAAS,iBAAkB,UAAqB,WAAmC;AACzF,SAAO,QAAS,MAAM;AACrB,UAAM,MAAmB,CAAC;AAC1B,UAAM,OAAoB,CAAC;AAC3B,UAAM,SAAwB,CAAC;AAC/B,UAAM,QAAqB,CAAC;AAC5B,UAAM,YAAyB,CAAC;AAEhC,aAAS,QAAS,UAAU,WAAS;AACpC,UAAK,eAAgB,KAAM,GAAI;AAE9B,YAAK,MAAM,SAAS,QAAS;AAC5B,gBAAM,cAAc,MAAM,OAAO;AACjC,gBAAM,WACL,gBAAgB,SAAS,gBAAgB,WAAW,cAAc;AAEnE,iBAAO,KAAM,EAAE,SAAS,OAAuB,SAAS,CAAE;AAE1D;AAAA,QACD;AAGA,cAAM,YAAY,MAAM;AACxB,cAAM,cAAc,WAAW;AAG/B,YAAK,gBAAgB,GAAI,SAAU,UAAU,gBAAgB,aAAc;AAE1E,cAAK,MAAM,OAAO,UAAW;AAC5B,qBAAS,QAAS,MAAM,MAAM,UAAU,cAAY;AACnD,kBAAI,KAAM,QAAS;AAAA,YACpB,CAAE;AAAA,UACH;AAAA,QACD,WAAY,gBAAgB,GAAI,SAAU,WAAW,gBAAgB,cAAe;AAEnF,cAAK,MAAM,OAAO,UAAW;AAC5B,qBAAS,QAAS,MAAM,MAAM,UAAU,eAAa;AACpD,mBAAK,KAAM,SAAU;AAAA,YACtB,CAAE;AAAA,UACH;AAAA,QACD,WAAY,MAAM,SAAS,OAAQ;AAElC,cAAI,KAAM,KAAM;AAAA,QACjB,OAAO;AACN,gBAAM,KAAM,KAAM;AAAA,QACnB;AAAA,MACD;AAGA,gBAAU,KAAM,KAAM;AAAA,IACvB,CAAE;AAEF,WAAO;AAAA,MACN,aAAa;AAAA,MACb,cAAc;AAAA,MACd,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,mBAAmB;AAAA,IACpB;AAAA,EACD,GAAG,CAAE,UAAU,SAAU,CAAE;AAC5B;","names":["_Fragment","_jsx"]}
@@ -1,51 +0,0 @@
1
- // src/charts/private/radial-wipe-animation/radial-wipe-animation.tsx
2
- import { jsx as _jsx } from "react/jsx-runtime";
3
- function RadialWipeAnimation({
4
- id,
5
- radius,
6
- innerRadius = 0,
7
- durationMs = 1e3,
8
- wipePercentage = 100,
9
- direction = "clockwise",
10
- startAngle = "-90deg"
11
- }) {
12
- const strokeWidth = (radius - innerRadius) * 2 + // The stroke is centered on the circumference, so we need to double the width.
13
- 1;
14
- const scaleY = direction === "clockwise" ? -1 : 1;
15
- const isValidWipePercentage = 0 < wipePercentage && wipePercentage <= 100;
16
- const animationDuration = `${// If wipePercentage is invalid, set animation duration to 0 to disable animation.
17
- isValidWipePercentage ? durationMs * (100 / wipePercentage) : 0}ms`;
18
- return /* @__PURE__ */ _jsx("mask", {
19
- id,
20
- children: /* @__PURE__ */ _jsx("circle", {
21
- cx: 0,
22
- cy: 0,
23
- r: radius,
24
- pathLength: "100",
25
- fill: "white",
26
- stroke: "black",
27
- strokeWidth,
28
- strokeDasharray: "100, 1000",
29
- strokeDashoffset: "0",
30
- style: {
31
- transform: `rotate(${startAngle}) scaleY(${scaleY})`
32
- },
33
- children: /* @__PURE__ */ _jsx("animate", {
34
- attributeName: "stroke-dashoffset",
35
- from: "0",
36
- to: "100.1",
37
- dur: animationDuration,
38
- fill: "freeze",
39
- calcMode: "spline",
40
- keySplines: "0.42 0 0.58 1;0 0 1 1",
41
- keyTimes: `0;${wipePercentage / 100};1`
42
- })
43
- })
44
- });
45
- }
46
- var radial_wipe_animation_default = RadialWipeAnimation;
47
-
48
- export {
49
- radial_wipe_animation_default
50
- };
51
- //# sourceMappingURL=chunk-KXRWNFQJ.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/charts/private/radial-wipe-animation/radial-wipe-animation.tsx"],"sourcesContent":["import { jsx as _jsx } from \"react/jsx-runtime\";\n/**\n * This animation uses the SVG self-drawing technique (source: https://www.joshwcomeau.com/svg/friendly-introduction-to-svg/),\n * leveraging stroke-dasharray and stroke-dashoffset properties to create the effect.\n *\n * Here, we reverse the animation to \"un-draw\" the circle for the revealing / radial wipe effect:\n * - Initially, the entire circle is drawn with a white mask.\n * - The circle's border (stroke) is drawn with a black stroke, wide enough to cover the circle.\n * - The stroke is then \"un-drawn,\" creating the wipe animation.\n * - A white mask makes the area visible, while a black mask makes the area invisible.\n */\n\n/**\n * RadialWipeAnimationProps - SVG mask props that requires a radial wipe animation effect.\n *\n * @param {object} props - The properties object.\n * @param {string} props.id - The unique ID for the mask.\n * @param {number} props.radius - The outer radius of the radial wipe.\n * @param {number} [props.innerRadius=0] - The inner radius of the radial wipe.\n * @param {number} [props.durationMs=1000] - The duration of the animation in milliseconds.\n * @param {number} [props.wipePercentage=100] - The percentage of the wipe animation to complete.\n * @param {'clockwise' | 'counter-clockwise'} [props.direction='clockwise'] - The direction of the wipe animation.\n * @param {Angle} [props.startAngle='-90deg'] - The starting angle of the wipe animation.\n *\n * @return {JSX.Element} The radial wipe mask element.\n */\n\n/**\n * Renders a SVG mask that creates a radial wipe animation effect.\n *\n * @param {RadialWipeAnimationProps} props - Component props\n * @return {JSX.Element} The rendered mask component\n */\nfunction RadialWipeAnimation({\n id,\n radius,\n innerRadius = 0,\n durationMs = 1000,\n wipePercentage = 100,\n direction = 'clockwise',\n startAngle = '-90deg'\n}) {\n const strokeWidth = (radius - innerRadius) * 2 +\n // The stroke is centered on the circumference, so we need to double the width.\n 1; // Added 1 to prevent sub-pixel rendering issues.\n\n const scaleY = direction === 'clockwise' ? -1 : 1;\n const isValidWipePercentage = 0 < wipePercentage && wipePercentage <= 100;\n const animationDuration = `${\n // If wipePercentage is invalid, set animation duration to 0 to disable animation.\n isValidWipePercentage ? durationMs * (100 / wipePercentage) : 0}ms`;\n return /*#__PURE__*/_jsx(\"mask\", {\n id: id,\n children: /*#__PURE__*/_jsx(\"circle\", {\n cx: 0,\n cy: 0,\n r: radius,\n pathLength: \"100\",\n fill: \"white\",\n stroke: \"black\" // The stroke will be un-drawn, hence 'black' mask.\n ,\n strokeWidth: strokeWidth,\n strokeDasharray: \"100, 1000\",\n strokeDashoffset: \"0\",\n style: {\n transform: `rotate(${startAngle}) scaleY(${scaleY})`\n },\n children: /*#__PURE__*/_jsx(\"animate\", {\n attributeName: \"stroke-dashoffset\",\n from: \"0\",\n to: \"100.1\",\n dur: animationDuration,\n fill: \"freeze\" // Same as CSS 'forwards' to retain the final state after animation.\n ,\n calcMode: \"spline\" // custom easing\n ,\n keySplines: \"0.42 0 0.58 1;0 0 1 1\" // ease-in-out ; linear (unimportant)\n ,\n keyTimes: `0;${wipePercentage / 100};1`\n })\n })\n });\n}\nexport default RadialWipeAnimation;"],"mappings":";AAAA,SAAS,OAAO,YAAY;AAiC5B,SAAS,oBAAoB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,aAAa;AAAA,EACb,iBAAiB;AAAA,EACjB,YAAY;AAAA,EACZ,aAAa;AACf,GAAG;AACD,QAAM,eAAe,SAAS,eAAe;AAAA,EAE7C;AAEA,QAAM,SAAS,cAAc,cAAc,KAAK;AAChD,QAAM,wBAAwB,IAAI,kBAAkB,kBAAkB;AACtE,QAAM,oBAAoB;AAAA,EAE1B,wBAAwB,cAAc,MAAM,kBAAkB,CAAC;AAC/D,SAAoB,qBAAK,QAAQ;AAAA,IAC/B;AAAA,IACA,UAAuB,qBAAK,UAAU;AAAA,MACpC,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,GAAG;AAAA,MACH,YAAY;AAAA,MACZ,MAAM;AAAA,MACN,QAAQ;AAAA,MAER;AAAA,MACA,iBAAiB;AAAA,MACjB,kBAAkB;AAAA,MAClB,OAAO;AAAA,QACL,WAAW,UAAU,UAAU,YAAY,MAAM;AAAA,MACnD;AAAA,MACA,UAAuB,qBAAK,WAAW;AAAA,QACrC,eAAe;AAAA,QACf,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,KAAK;AAAA,QACL,MAAM;AAAA,QAEN,UAAU;AAAA,QAEV,YAAY;AAAA,QAEZ,UAAU,KAAK,iBAAiB,GAAG;AAAA,MACrC,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC;AACH;AACA,IAAO,gCAAQ;","names":[]}