@automattic/charts 0.16.2 → 0.18.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 (330) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/cjs/_virtual/index.js +2 -0
  3. package/dist/cjs/_virtual/index.js.map +1 -0
  4. package/dist/cjs/_virtual/react-is.development.js +2 -0
  5. package/dist/cjs/_virtual/react-is.development.js.map +1 -0
  6. package/dist/cjs/_virtual/react-is.production.min.js +2 -0
  7. package/dist/cjs/_virtual/react-is.production.min.js.map +1 -0
  8. package/dist/cjs/_virtual/sprintf.js +2 -0
  9. package/dist/cjs/_virtual/sprintf.js.map +1 -0
  10. package/dist/cjs/components/bar-chart/bar-chart.js +1 -1
  11. package/dist/cjs/components/bar-chart/bar-chart.js.map +1 -1
  12. package/dist/cjs/components/bar-chart/use-bar-chart-options.js +1 -1
  13. package/dist/cjs/components/bar-chart/use-bar-chart-options.js.map +1 -1
  14. package/dist/cjs/components/bar-list-chart/bar-list-chart.js +1 -1
  15. package/dist/cjs/components/bar-list-chart/bar-list-chart.js.map +1 -1
  16. package/dist/cjs/components/leaderboard-chart/leaderboard-chart.js +2 -0
  17. package/dist/cjs/components/leaderboard-chart/leaderboard-chart.js.map +1 -0
  18. package/dist/cjs/components/leaderboard-chart/leaderboard-chart.module.scss.js +2 -0
  19. package/dist/cjs/components/leaderboard-chart/leaderboard-chart.module.scss.js.map +1 -0
  20. package/dist/cjs/components/legend/base-legend.js +1 -1
  21. package/dist/cjs/components/legend/base-legend.js.map +1 -1
  22. package/dist/cjs/components/line-chart/line-chart-annotation-label-popover.js +2 -0
  23. package/dist/cjs/components/line-chart/line-chart-annotation-label-popover.js.map +1 -0
  24. package/dist/cjs/components/line-chart/line-chart-annotation.js +1 -1
  25. package/dist/cjs/components/line-chart/line-chart-annotation.js.map +1 -1
  26. package/dist/cjs/components/line-chart/line-chart-annotations-overlay.js +2 -0
  27. package/dist/cjs/components/line-chart/line-chart-annotations-overlay.js.map +1 -0
  28. package/dist/cjs/components/line-chart/line-chart-context.js +2 -0
  29. package/dist/cjs/components/line-chart/line-chart-context.js.map +1 -0
  30. package/dist/cjs/components/line-chart/line-chart.js +1 -1
  31. package/dist/cjs/components/line-chart/line-chart.js.map +1 -1
  32. package/dist/cjs/components/line-chart/line-chart.module.scss.js +1 -1
  33. package/dist/cjs/components/pie-chart/pie-chart.js +1 -1
  34. package/dist/cjs/components/pie-chart/pie-chart.js.map +1 -1
  35. package/dist/cjs/components/pie-semi-circle-chart/pie-semi-circle-chart.js +1 -1
  36. package/dist/cjs/components/pie-semi-circle-chart/pie-semi-circle-chart.js.map +1 -1
  37. package/dist/cjs/components/shared/format-metric-value.js +2 -0
  38. package/dist/cjs/components/shared/format-metric-value.js.map +1 -0
  39. package/dist/cjs/components/shared/use-chart-data-transform.js +1 -1
  40. package/dist/cjs/components/shared/use-chart-data-transform.js.map +1 -1
  41. package/dist/cjs/components/shared/use-chart-margin.js +1 -1
  42. package/dist/cjs/components/shared/use-chart-margin.js.map +1 -1
  43. package/dist/cjs/components/shared/use-element-height.js +1 -1
  44. package/dist/cjs/components/shared/use-element-height.js.map +1 -1
  45. package/dist/cjs/components/shared/utils.js +1 -1
  46. package/dist/cjs/components/shared/utils.js.map +1 -1
  47. package/dist/cjs/components/tooltip/accessible-tooltip.js +2 -0
  48. package/dist/cjs/components/tooltip/accessible-tooltip.js.map +1 -0
  49. package/dist/cjs/hooks/use-chart-mouse-handler.js +1 -1
  50. package/dist/cjs/hooks/use-chart-mouse-handler.js.map +1 -1
  51. package/dist/cjs/index.js +1 -1
  52. package/dist/cjs/node_modules/.pnpm/@emotion_cache@11.14.0/node_modules/@emotion/cache/dist/emotion-cache.esm.js +2 -0
  53. package/dist/cjs/node_modules/.pnpm/@emotion_cache@11.14.0/node_modules/@emotion/cache/dist/emotion-cache.esm.js.map +1 -0
  54. package/dist/cjs/node_modules/.pnpm/@emotion_hash@0.9.2/node_modules/@emotion/hash/dist/emotion-hash.esm.js +2 -0
  55. package/dist/cjs/node_modules/.pnpm/@emotion_hash@0.9.2/node_modules/@emotion/hash/dist/emotion-hash.esm.js.map +1 -0
  56. package/dist/cjs/node_modules/.pnpm/@emotion_is-prop-valid@1.3.1/node_modules/@emotion/is-prop-valid/dist/emotion-is-prop-valid.esm.js +2 -0
  57. package/dist/cjs/node_modules/.pnpm/@emotion_is-prop-valid@1.3.1/node_modules/@emotion/is-prop-valid/dist/emotion-is-prop-valid.esm.js.map +1 -0
  58. package/dist/cjs/node_modules/.pnpm/@emotion_memoize@0.9.0/node_modules/@emotion/memoize/dist/emotion-memoize.esm.js +2 -0
  59. package/dist/cjs/node_modules/.pnpm/@emotion_memoize@0.9.0/node_modules/@emotion/memoize/dist/emotion-memoize.esm.js.map +1 -0
  60. package/dist/cjs/node_modules/.pnpm/@emotion_react@11.14.0_@types_react@18.3.23_react@18.3.1/node_modules/@emotion/react/dist/emotion-element-d59e098f.esm.js +2 -0
  61. package/dist/cjs/node_modules/.pnpm/@emotion_react@11.14.0_@types_react@18.3.23_react@18.3.1/node_modules/@emotion/react/dist/emotion-element-d59e098f.esm.js.map +1 -0
  62. package/dist/cjs/node_modules/.pnpm/@emotion_react@11.14.0_@types_react@18.3.23_react@18.3.1/node_modules/@emotion/react/dist/emotion-react.esm.js +2 -0
  63. package/dist/cjs/node_modules/.pnpm/@emotion_react@11.14.0_@types_react@18.3.23_react@18.3.1/node_modules/@emotion/react/dist/emotion-react.esm.js.map +1 -0
  64. package/dist/cjs/node_modules/.pnpm/@emotion_serialize@1.3.3/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js +2 -0
  65. package/dist/cjs/node_modules/.pnpm/@emotion_serialize@1.3.3/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js.map +1 -0
  66. package/dist/cjs/node_modules/.pnpm/@emotion_sheet@1.4.0/node_modules/@emotion/sheet/dist/emotion-sheet.esm.js +2 -0
  67. package/dist/cjs/node_modules/.pnpm/@emotion_sheet@1.4.0/node_modules/@emotion/sheet/dist/emotion-sheet.esm.js.map +1 -0
  68. package/dist/cjs/node_modules/.pnpm/@emotion_styled@11.14.0_@emotion_react@11.14.0_@types_react@18.3.23_react@18.3.1__@types_react@18.3.23_react@18.3.1/node_modules/@emotion/styled/base/dist/emotion-styled-base.esm.js +2 -0
  69. package/dist/cjs/node_modules/.pnpm/@emotion_styled@11.14.0_@emotion_react@11.14.0_@types_react@18.3.23_react@18.3.1__@types_react@18.3.23_react@18.3.1/node_modules/@emotion/styled/base/dist/emotion-styled-base.esm.js.map +1 -0
  70. package/dist/cjs/node_modules/.pnpm/@emotion_unitless@0.10.0/node_modules/@emotion/unitless/dist/emotion-unitless.esm.js +2 -0
  71. package/dist/cjs/node_modules/.pnpm/@emotion_unitless@0.10.0/node_modules/@emotion/unitless/dist/emotion-unitless.esm.js.map +1 -0
  72. package/dist/cjs/node_modules/.pnpm/@emotion_use-insertion-effect-with-fallbacks@1.2.0_react@18.3.1/node_modules/@emotion/use-insertion-effect-with-fallbacks/dist/emotion-use-insertion-effect-with-fallbacks.esm.js +2 -0
  73. package/dist/cjs/node_modules/.pnpm/@emotion_use-insertion-effect-with-fallbacks@1.2.0_react@18.3.1/node_modules/@emotion/use-insertion-effect-with-fallbacks/dist/emotion-use-insertion-effect-with-fallbacks.esm.js.map +1 -0
  74. package/dist/cjs/node_modules/.pnpm/@emotion_utils@1.4.2/node_modules/@emotion/utils/dist/emotion-utils.esm.js +2 -0
  75. package/dist/cjs/node_modules/.pnpm/@emotion_utils@1.4.2/node_modules/@emotion/utils/dist/emotion-utils.esm.js.map +1 -0
  76. package/dist/cjs/node_modules/.pnpm/@emotion_weak-memoize@0.4.0/node_modules/@emotion/weak-memoize/dist/emotion-weak-memoize.esm.js +2 -0
  77. package/dist/cjs/node_modules/.pnpm/@emotion_weak-memoize@0.4.0/node_modules/@emotion/weak-memoize/dist/emotion-weak-memoize.esm.js.map +1 -0
  78. package/dist/cjs/node_modules/.pnpm/@tannin_compile@1.1.0/node_modules/@tannin/compile/index.js +2 -0
  79. package/dist/cjs/node_modules/.pnpm/@tannin_compile@1.1.0/node_modules/@tannin/compile/index.js.map +1 -0
  80. package/dist/cjs/node_modules/.pnpm/@tannin_evaluate@1.2.0/node_modules/@tannin/evaluate/index.js +2 -0
  81. package/dist/cjs/node_modules/.pnpm/@tannin_evaluate@1.2.0/node_modules/@tannin/evaluate/index.js.map +1 -0
  82. package/dist/cjs/node_modules/.pnpm/@tannin_plural-forms@1.1.0/node_modules/@tannin/plural-forms/index.js +2 -0
  83. package/dist/cjs/node_modules/.pnpm/@tannin_plural-forms@1.1.0/node_modules/@tannin/plural-forms/index.js.map +1 -0
  84. package/dist/cjs/node_modules/.pnpm/@tannin_postfix@1.1.0/node_modules/@tannin/postfix/index.js +2 -0
  85. package/dist/cjs/node_modules/.pnpm/@tannin_postfix@1.1.0/node_modules/@tannin/postfix/index.js.map +1 -0
  86. package/dist/cjs/node_modules/.pnpm/@wordpress_components@29.12.0_@types_react@18.3.23_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/progress-bar/index.js +2 -0
  87. package/dist/cjs/node_modules/.pnpm/@wordpress_components@29.12.0_@types_react@18.3.23_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/progress-bar/index.js.map +1 -0
  88. package/dist/cjs/node_modules/.pnpm/@wordpress_components@29.12.0_@types_react@18.3.23_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/progress-bar/styles.js +2 -0
  89. package/dist/cjs/node_modules/.pnpm/@wordpress_components@29.12.0_@types_react@18.3.23_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/progress-bar/styles.js.map +1 -0
  90. package/dist/cjs/node_modules/.pnpm/@wordpress_components@29.12.0_@types_react@18.3.23_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/utils/colors-values.js +2 -0
  91. package/dist/cjs/node_modules/.pnpm/@wordpress_components@29.12.0_@types_react@18.3.23_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/utils/colors-values.js.map +1 -0
  92. package/dist/cjs/node_modules/.pnpm/@wordpress_components@29.12.0_@types_react@18.3.23_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/utils/config-values.js +2 -0
  93. package/dist/cjs/node_modules/.pnpm/@wordpress_components@29.12.0_@types_react@18.3.23_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/utils/config-values.js.map +1 -0
  94. package/dist/cjs/node_modules/.pnpm/@wordpress_components@29.12.0_@types_react@18.3.23_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/utils/space.js +2 -0
  95. package/dist/cjs/node_modules/.pnpm/@wordpress_components@29.12.0_@types_react@18.3.23_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/utils/space.js.map +1 -0
  96. package/dist/cjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createAddHook.js +2 -0
  97. package/dist/cjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createAddHook.js.map +1 -0
  98. package/dist/cjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createCurrentHook.js +2 -0
  99. package/dist/cjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createCurrentHook.js.map +1 -0
  100. package/dist/cjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createDidHook.js +2 -0
  101. package/dist/cjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createDidHook.js.map +1 -0
  102. package/dist/cjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createDoingHook.js +2 -0
  103. package/dist/cjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createDoingHook.js.map +1 -0
  104. package/dist/cjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createHasHook.js +2 -0
  105. package/dist/cjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createHasHook.js.map +1 -0
  106. package/dist/cjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createHooks.js +2 -0
  107. package/dist/cjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createHooks.js.map +1 -0
  108. package/dist/cjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createRemoveHook.js +2 -0
  109. package/dist/cjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createRemoveHook.js.map +1 -0
  110. package/dist/cjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createRunHook.js +2 -0
  111. package/dist/cjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createRunHook.js.map +1 -0
  112. package/dist/cjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/index.js +2 -0
  113. package/dist/cjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/index.js.map +1 -0
  114. package/dist/cjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/validateHookName.js +2 -0
  115. package/dist/cjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/validateHookName.js.map +1 -0
  116. package/dist/cjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/validateNamespace.js +2 -0
  117. package/dist/cjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/validateNamespace.js.map +1 -0
  118. package/dist/cjs/node_modules/.pnpm/@wordpress_i18n@5.26.0/node_modules/@wordpress/i18n/build-module/create-i18n.js +2 -0
  119. package/dist/cjs/node_modules/.pnpm/@wordpress_i18n@5.26.0/node_modules/@wordpress/i18n/build-module/create-i18n.js.map +1 -0
  120. package/dist/cjs/node_modules/.pnpm/@wordpress_i18n@5.26.0/node_modules/@wordpress/i18n/build-module/default-i18n.js +2 -0
  121. package/dist/cjs/node_modules/.pnpm/@wordpress_i18n@5.26.0/node_modules/@wordpress/i18n/build-module/default-i18n.js.map +1 -0
  122. package/dist/cjs/node_modules/.pnpm/hoist-non-react-statics@3.3.2/node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js +2 -0
  123. package/dist/cjs/node_modules/.pnpm/hoist-non-react-statics@3.3.2/node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js.map +1 -0
  124. package/dist/cjs/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/cjs/react-is.development.js +10 -0
  125. package/dist/cjs/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/cjs/react-is.development.js.map +1 -0
  126. package/dist/cjs/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/cjs/react-is.production.min.js +10 -0
  127. package/dist/cjs/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/cjs/react-is.production.min.js.map +1 -0
  128. package/dist/cjs/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/index.js +2 -0
  129. package/dist/cjs/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/index.js.map +1 -0
  130. package/dist/cjs/node_modules/.pnpm/sprintf-js@1.1.3/node_modules/sprintf-js/src/sprintf.js +2 -0
  131. package/dist/cjs/node_modules/.pnpm/sprintf-js@1.1.3/node_modules/sprintf-js/src/sprintf.js.map +1 -0
  132. package/dist/cjs/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Enum.js +2 -0
  133. package/dist/cjs/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Enum.js.map +1 -0
  134. package/dist/cjs/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Middleware.js +2 -0
  135. package/dist/cjs/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Middleware.js.map +1 -0
  136. package/dist/cjs/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Parser.js +2 -0
  137. package/dist/cjs/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Parser.js.map +1 -0
  138. package/dist/cjs/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Serializer.js +2 -0
  139. package/dist/cjs/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Serializer.js.map +1 -0
  140. package/dist/cjs/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Tokenizer.js +2 -0
  141. package/dist/cjs/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Tokenizer.js.map +1 -0
  142. package/dist/cjs/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Utility.js +2 -0
  143. package/dist/cjs/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Utility.js.map +1 -0
  144. package/dist/cjs/node_modules/.pnpm/tannin@1.2.0/node_modules/tannin/index.js +2 -0
  145. package/dist/cjs/node_modules/.pnpm/tannin@1.2.0/node_modules/tannin/index.js.map +1 -0
  146. package/dist/cjs/providers/chart-context/chart-context.js +2 -0
  147. package/dist/cjs/providers/chart-context/chart-context.js.map +1 -0
  148. package/dist/cjs/providers/chart-context/utils.js +2 -0
  149. package/dist/cjs/providers/chart-context/utils.js.map +1 -0
  150. package/dist/cjs/providers/theme/theme-provider.js +1 -1
  151. package/dist/cjs/providers/theme/theme-provider.js.map +1 -1
  152. package/dist/cjs/style.css +1 -1
  153. package/dist/index.d.ts +151 -20
  154. package/dist/mjs/_virtual/index.js +2 -0
  155. package/dist/mjs/_virtual/index.js.map +1 -0
  156. package/dist/mjs/_virtual/react-is.development.js +2 -0
  157. package/dist/mjs/_virtual/react-is.development.js.map +1 -0
  158. package/dist/mjs/_virtual/react-is.production.min.js +2 -0
  159. package/dist/mjs/_virtual/react-is.production.min.js.map +1 -0
  160. package/dist/mjs/_virtual/sprintf.js +2 -0
  161. package/dist/mjs/_virtual/sprintf.js.map +1 -0
  162. package/dist/mjs/components/bar-chart/bar-chart.js +1 -1
  163. package/dist/mjs/components/bar-chart/bar-chart.js.map +1 -1
  164. package/dist/mjs/components/bar-chart/use-bar-chart-options.js +1 -1
  165. package/dist/mjs/components/bar-chart/use-bar-chart-options.js.map +1 -1
  166. package/dist/mjs/components/bar-list-chart/bar-list-chart.js +1 -1
  167. package/dist/mjs/components/bar-list-chart/bar-list-chart.js.map +1 -1
  168. package/dist/mjs/components/leaderboard-chart/leaderboard-chart.js +2 -0
  169. package/dist/mjs/components/leaderboard-chart/leaderboard-chart.js.map +1 -0
  170. package/dist/mjs/components/leaderboard-chart/leaderboard-chart.module.scss.js +2 -0
  171. package/dist/mjs/components/leaderboard-chart/leaderboard-chart.module.scss.js.map +1 -0
  172. package/dist/mjs/components/legend/base-legend.js +1 -1
  173. package/dist/mjs/components/legend/base-legend.js.map +1 -1
  174. package/dist/mjs/components/line-chart/line-chart-annotation-label-popover.js +2 -0
  175. package/dist/mjs/components/line-chart/line-chart-annotation-label-popover.js.map +1 -0
  176. package/dist/mjs/components/line-chart/line-chart-annotation.js +1 -1
  177. package/dist/mjs/components/line-chart/line-chart-annotation.js.map +1 -1
  178. package/dist/mjs/components/line-chart/line-chart-annotations-overlay.js +2 -0
  179. package/dist/mjs/components/line-chart/line-chart-annotations-overlay.js.map +1 -0
  180. package/dist/mjs/components/line-chart/line-chart-context.js +2 -0
  181. package/dist/mjs/components/line-chart/line-chart-context.js.map +1 -0
  182. package/dist/mjs/components/line-chart/line-chart.js +1 -1
  183. package/dist/mjs/components/line-chart/line-chart.js.map +1 -1
  184. package/dist/mjs/components/line-chart/line-chart.module.scss.js +1 -1
  185. package/dist/mjs/components/pie-chart/pie-chart.js +1 -1
  186. package/dist/mjs/components/pie-chart/pie-chart.js.map +1 -1
  187. package/dist/mjs/components/pie-semi-circle-chart/pie-semi-circle-chart.js +1 -1
  188. package/dist/mjs/components/pie-semi-circle-chart/pie-semi-circle-chart.js.map +1 -1
  189. package/dist/mjs/components/shared/format-metric-value.js +2 -0
  190. package/dist/mjs/components/shared/format-metric-value.js.map +1 -0
  191. package/dist/mjs/components/shared/use-chart-data-transform.js +1 -1
  192. package/dist/mjs/components/shared/use-chart-data-transform.js.map +1 -1
  193. package/dist/mjs/components/shared/use-chart-margin.js +1 -1
  194. package/dist/mjs/components/shared/use-chart-margin.js.map +1 -1
  195. package/dist/mjs/components/shared/use-element-height.js +1 -1
  196. package/dist/mjs/components/shared/use-element-height.js.map +1 -1
  197. package/dist/mjs/components/shared/utils.js +1 -1
  198. package/dist/mjs/components/shared/utils.js.map +1 -1
  199. package/dist/mjs/components/tooltip/accessible-tooltip.js +2 -0
  200. package/dist/mjs/components/tooltip/accessible-tooltip.js.map +1 -0
  201. package/dist/mjs/hooks/use-chart-mouse-handler.js +1 -1
  202. package/dist/mjs/hooks/use-chart-mouse-handler.js.map +1 -1
  203. package/dist/mjs/index.js +1 -1
  204. package/dist/mjs/node_modules/.pnpm/@emotion_cache@11.14.0/node_modules/@emotion/cache/dist/emotion-cache.esm.js +2 -0
  205. package/dist/mjs/node_modules/.pnpm/@emotion_cache@11.14.0/node_modules/@emotion/cache/dist/emotion-cache.esm.js.map +1 -0
  206. package/dist/mjs/node_modules/.pnpm/@emotion_hash@0.9.2/node_modules/@emotion/hash/dist/emotion-hash.esm.js +2 -0
  207. package/dist/mjs/node_modules/.pnpm/@emotion_hash@0.9.2/node_modules/@emotion/hash/dist/emotion-hash.esm.js.map +1 -0
  208. package/dist/mjs/node_modules/.pnpm/@emotion_is-prop-valid@1.3.1/node_modules/@emotion/is-prop-valid/dist/emotion-is-prop-valid.esm.js +2 -0
  209. package/dist/mjs/node_modules/.pnpm/@emotion_is-prop-valid@1.3.1/node_modules/@emotion/is-prop-valid/dist/emotion-is-prop-valid.esm.js.map +1 -0
  210. package/dist/mjs/node_modules/.pnpm/@emotion_memoize@0.9.0/node_modules/@emotion/memoize/dist/emotion-memoize.esm.js +2 -0
  211. package/dist/mjs/node_modules/.pnpm/@emotion_memoize@0.9.0/node_modules/@emotion/memoize/dist/emotion-memoize.esm.js.map +1 -0
  212. package/dist/mjs/node_modules/.pnpm/@emotion_react@11.14.0_@types_react@18.3.23_react@18.3.1/node_modules/@emotion/react/dist/emotion-element-d59e098f.esm.js +2 -0
  213. package/dist/mjs/node_modules/.pnpm/@emotion_react@11.14.0_@types_react@18.3.23_react@18.3.1/node_modules/@emotion/react/dist/emotion-element-d59e098f.esm.js.map +1 -0
  214. package/dist/mjs/node_modules/.pnpm/@emotion_react@11.14.0_@types_react@18.3.23_react@18.3.1/node_modules/@emotion/react/dist/emotion-react.esm.js +2 -0
  215. package/dist/mjs/node_modules/.pnpm/@emotion_react@11.14.0_@types_react@18.3.23_react@18.3.1/node_modules/@emotion/react/dist/emotion-react.esm.js.map +1 -0
  216. package/dist/mjs/node_modules/.pnpm/@emotion_serialize@1.3.3/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js +2 -0
  217. package/dist/mjs/node_modules/.pnpm/@emotion_serialize@1.3.3/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js.map +1 -0
  218. package/dist/mjs/node_modules/.pnpm/@emotion_sheet@1.4.0/node_modules/@emotion/sheet/dist/emotion-sheet.esm.js +2 -0
  219. package/dist/mjs/node_modules/.pnpm/@emotion_sheet@1.4.0/node_modules/@emotion/sheet/dist/emotion-sheet.esm.js.map +1 -0
  220. package/dist/mjs/node_modules/.pnpm/@emotion_styled@11.14.0_@emotion_react@11.14.0_@types_react@18.3.23_react@18.3.1__@types_react@18.3.23_react@18.3.1/node_modules/@emotion/styled/base/dist/emotion-styled-base.esm.js +2 -0
  221. package/dist/mjs/node_modules/.pnpm/@emotion_styled@11.14.0_@emotion_react@11.14.0_@types_react@18.3.23_react@18.3.1__@types_react@18.3.23_react@18.3.1/node_modules/@emotion/styled/base/dist/emotion-styled-base.esm.js.map +1 -0
  222. package/dist/mjs/node_modules/.pnpm/@emotion_unitless@0.10.0/node_modules/@emotion/unitless/dist/emotion-unitless.esm.js +2 -0
  223. package/dist/mjs/node_modules/.pnpm/@emotion_unitless@0.10.0/node_modules/@emotion/unitless/dist/emotion-unitless.esm.js.map +1 -0
  224. package/dist/mjs/node_modules/.pnpm/@emotion_use-insertion-effect-with-fallbacks@1.2.0_react@18.3.1/node_modules/@emotion/use-insertion-effect-with-fallbacks/dist/emotion-use-insertion-effect-with-fallbacks.esm.js +2 -0
  225. package/dist/mjs/node_modules/.pnpm/@emotion_use-insertion-effect-with-fallbacks@1.2.0_react@18.3.1/node_modules/@emotion/use-insertion-effect-with-fallbacks/dist/emotion-use-insertion-effect-with-fallbacks.esm.js.map +1 -0
  226. package/dist/mjs/node_modules/.pnpm/@emotion_utils@1.4.2/node_modules/@emotion/utils/dist/emotion-utils.esm.js +2 -0
  227. package/dist/mjs/node_modules/.pnpm/@emotion_utils@1.4.2/node_modules/@emotion/utils/dist/emotion-utils.esm.js.map +1 -0
  228. package/dist/mjs/node_modules/.pnpm/@emotion_weak-memoize@0.4.0/node_modules/@emotion/weak-memoize/dist/emotion-weak-memoize.esm.js +2 -0
  229. package/dist/mjs/node_modules/.pnpm/@emotion_weak-memoize@0.4.0/node_modules/@emotion/weak-memoize/dist/emotion-weak-memoize.esm.js.map +1 -0
  230. package/dist/mjs/node_modules/.pnpm/@tannin_compile@1.1.0/node_modules/@tannin/compile/index.js +2 -0
  231. package/dist/mjs/node_modules/.pnpm/@tannin_compile@1.1.0/node_modules/@tannin/compile/index.js.map +1 -0
  232. package/dist/mjs/node_modules/.pnpm/@tannin_evaluate@1.2.0/node_modules/@tannin/evaluate/index.js +2 -0
  233. package/dist/mjs/node_modules/.pnpm/@tannin_evaluate@1.2.0/node_modules/@tannin/evaluate/index.js.map +1 -0
  234. package/dist/mjs/node_modules/.pnpm/@tannin_plural-forms@1.1.0/node_modules/@tannin/plural-forms/index.js +2 -0
  235. package/dist/mjs/node_modules/.pnpm/@tannin_plural-forms@1.1.0/node_modules/@tannin/plural-forms/index.js.map +1 -0
  236. package/dist/mjs/node_modules/.pnpm/@tannin_postfix@1.1.0/node_modules/@tannin/postfix/index.js +2 -0
  237. package/dist/mjs/node_modules/.pnpm/@tannin_postfix@1.1.0/node_modules/@tannin/postfix/index.js.map +1 -0
  238. package/dist/mjs/node_modules/.pnpm/@wordpress_components@29.12.0_@types_react@18.3.23_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/progress-bar/index.js +2 -0
  239. package/dist/mjs/node_modules/.pnpm/@wordpress_components@29.12.0_@types_react@18.3.23_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/progress-bar/index.js.map +1 -0
  240. package/dist/mjs/node_modules/.pnpm/@wordpress_components@29.12.0_@types_react@18.3.23_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/progress-bar/styles.js +2 -0
  241. package/dist/mjs/node_modules/.pnpm/@wordpress_components@29.12.0_@types_react@18.3.23_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/progress-bar/styles.js.map +1 -0
  242. package/dist/mjs/node_modules/.pnpm/@wordpress_components@29.12.0_@types_react@18.3.23_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/utils/colors-values.js +2 -0
  243. package/dist/mjs/node_modules/.pnpm/@wordpress_components@29.12.0_@types_react@18.3.23_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/utils/colors-values.js.map +1 -0
  244. package/dist/mjs/node_modules/.pnpm/@wordpress_components@29.12.0_@types_react@18.3.23_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/utils/config-values.js +2 -0
  245. package/dist/mjs/node_modules/.pnpm/@wordpress_components@29.12.0_@types_react@18.3.23_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/utils/config-values.js.map +1 -0
  246. package/dist/mjs/node_modules/.pnpm/@wordpress_components@29.12.0_@types_react@18.3.23_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/utils/space.js +2 -0
  247. package/dist/mjs/node_modules/.pnpm/@wordpress_components@29.12.0_@types_react@18.3.23_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/utils/space.js.map +1 -0
  248. package/dist/mjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createAddHook.js +2 -0
  249. package/dist/mjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createAddHook.js.map +1 -0
  250. package/dist/mjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createCurrentHook.js +2 -0
  251. package/dist/mjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createCurrentHook.js.map +1 -0
  252. package/dist/mjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createDidHook.js +2 -0
  253. package/dist/mjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createDidHook.js.map +1 -0
  254. package/dist/mjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createDoingHook.js +2 -0
  255. package/dist/mjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createDoingHook.js.map +1 -0
  256. package/dist/mjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createHasHook.js +2 -0
  257. package/dist/mjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createHasHook.js.map +1 -0
  258. package/dist/mjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createHooks.js +2 -0
  259. package/dist/mjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createHooks.js.map +1 -0
  260. package/dist/mjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createRemoveHook.js +2 -0
  261. package/dist/mjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createRemoveHook.js.map +1 -0
  262. package/dist/mjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createRunHook.js +2 -0
  263. package/dist/mjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/createRunHook.js.map +1 -0
  264. package/dist/mjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/index.js +2 -0
  265. package/dist/mjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/index.js.map +1 -0
  266. package/dist/mjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/validateHookName.js +2 -0
  267. package/dist/mjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/validateHookName.js.map +1 -0
  268. package/dist/mjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/validateNamespace.js +2 -0
  269. package/dist/mjs/node_modules/.pnpm/@wordpress_hooks@4.26.0/node_modules/@wordpress/hooks/build-module/validateNamespace.js.map +1 -0
  270. package/dist/mjs/node_modules/.pnpm/@wordpress_i18n@5.26.0/node_modules/@wordpress/i18n/build-module/create-i18n.js +2 -0
  271. package/dist/mjs/node_modules/.pnpm/@wordpress_i18n@5.26.0/node_modules/@wordpress/i18n/build-module/create-i18n.js.map +1 -0
  272. package/dist/mjs/node_modules/.pnpm/@wordpress_i18n@5.26.0/node_modules/@wordpress/i18n/build-module/default-i18n.js +2 -0
  273. package/dist/mjs/node_modules/.pnpm/@wordpress_i18n@5.26.0/node_modules/@wordpress/i18n/build-module/default-i18n.js.map +1 -0
  274. package/dist/mjs/node_modules/.pnpm/hoist-non-react-statics@3.3.2/node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js +2 -0
  275. package/dist/mjs/node_modules/.pnpm/hoist-non-react-statics@3.3.2/node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js.map +1 -0
  276. package/dist/mjs/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/cjs/react-is.development.js +10 -0
  277. package/dist/mjs/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/cjs/react-is.development.js.map +1 -0
  278. package/dist/mjs/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/cjs/react-is.production.min.js +10 -0
  279. package/dist/mjs/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/cjs/react-is.production.min.js.map +1 -0
  280. package/dist/mjs/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/index.js +2 -0
  281. package/dist/mjs/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/index.js.map +1 -0
  282. package/dist/mjs/node_modules/.pnpm/sprintf-js@1.1.3/node_modules/sprintf-js/src/sprintf.js +2 -0
  283. package/dist/mjs/node_modules/.pnpm/sprintf-js@1.1.3/node_modules/sprintf-js/src/sprintf.js.map +1 -0
  284. package/dist/mjs/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Enum.js +2 -0
  285. package/dist/mjs/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Enum.js.map +1 -0
  286. package/dist/mjs/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Middleware.js +2 -0
  287. package/dist/mjs/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Middleware.js.map +1 -0
  288. package/dist/mjs/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Parser.js +2 -0
  289. package/dist/mjs/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Parser.js.map +1 -0
  290. package/dist/mjs/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Serializer.js +2 -0
  291. package/dist/mjs/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Serializer.js.map +1 -0
  292. package/dist/mjs/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Tokenizer.js +2 -0
  293. package/dist/mjs/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Tokenizer.js.map +1 -0
  294. package/dist/mjs/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Utility.js +2 -0
  295. package/dist/mjs/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Utility.js.map +1 -0
  296. package/dist/mjs/node_modules/.pnpm/tannin@1.2.0/node_modules/tannin/index.js +2 -0
  297. package/dist/mjs/node_modules/.pnpm/tannin@1.2.0/node_modules/tannin/index.js.map +1 -0
  298. package/dist/mjs/providers/chart-context/chart-context.js +2 -0
  299. package/dist/mjs/providers/chart-context/chart-context.js.map +1 -0
  300. package/dist/mjs/providers/chart-context/utils.js +2 -0
  301. package/dist/mjs/providers/chart-context/utils.js.map +1 -0
  302. package/dist/mjs/providers/theme/theme-provider.js +1 -1
  303. package/dist/mjs/providers/theme/theme-provider.js.map +1 -1
  304. package/dist/mjs/style.css +1 -1
  305. package/package.json +11 -9
  306. package/src/components/bar-chart/bar-chart.tsx +115 -22
  307. package/src/components/grid-control/grid-control.module.scss +6 -6
  308. package/src/components/leaderboard-chart/README.md +199 -0
  309. package/src/components/leaderboard-chart/index.tsx +4 -0
  310. package/src/components/leaderboard-chart/leaderboard-chart.module.scss +93 -0
  311. package/src/components/leaderboard-chart/leaderboard-chart.tsx +214 -0
  312. package/src/components/line-chart/line-chart-annotation-label-popover.tsx +110 -0
  313. package/src/components/line-chart/line-chart-annotation.tsx +123 -22
  314. package/src/components/line-chart/line-chart-annotations-overlay.tsx +135 -0
  315. package/src/components/line-chart/line-chart-context.tsx +28 -0
  316. package/src/components/line-chart/line-chart.module.scss +69 -1
  317. package/src/components/line-chart/line-chart.tsx +357 -361
  318. package/src/components/pie-chart/pie-chart.tsx +29 -8
  319. package/src/components/pie-semi-circle-chart/pie-semi-circle-chart.tsx +44 -21
  320. package/src/components/shared/format-metric-value.ts +92 -0
  321. package/src/components/shared/utils.ts +7 -0
  322. package/src/components/tooltip/accessible-tooltip.tsx +245 -0
  323. package/src/components/tooltip/base-tooltip.module.scss +9 -9
  324. package/src/index.ts +11 -0
  325. package/src/providers/chart-context/chart-context.test.tsx +230 -0
  326. package/src/providers/chart-context/chart-context.tsx +45 -0
  327. package/src/providers/chart-context/index.ts +3 -0
  328. package/src/providers/chart-context/types.ts +16 -0
  329. package/src/providers/chart-context/utils.ts +48 -0
  330. package/src/types.ts +29 -0
@@ -0,0 +1,214 @@
1
+ import { ProgressBar } from '@wordpress/components';
2
+ import clsx from 'clsx';
3
+ import { type FC } from 'react';
4
+ import { formatMetricValue } from '../shared/format-metric-value';
5
+ import styles from './leaderboard-chart.module.scss';
6
+ export interface LeaderboardEntry {
7
+ /**
8
+ * Unique internal key (e.g., 'key-direct')
9
+ */
10
+ id: string;
11
+
12
+ /**
13
+ * Human-readable name (e.g., 'Direct')
14
+ */
15
+ label: string;
16
+
17
+ /**
18
+ * Value of the entry
19
+ */
20
+ currentValue: number;
21
+
22
+ /**
23
+ * Value of the entry in the previous period
24
+ */
25
+ previousValue: number;
26
+
27
+ /**
28
+ * Width of current bar, as % of the current value
29
+ */
30
+ currentShare: number;
31
+
32
+ /**
33
+ * Width of previous bar, as % of the current value
34
+ */
35
+ previousShare: number;
36
+
37
+ /**
38
+ * Delta of the entry
39
+ */
40
+ delta: number;
41
+ }
42
+
43
+ export interface LeaderboardChartProps {
44
+ /**
45
+ * Array of leaderboard entries to display
46
+ */
47
+ data: LeaderboardEntry[];
48
+
49
+ /**
50
+ * Whether to show comparison data
51
+ */
52
+ withComparison?: boolean;
53
+
54
+ /**
55
+ * Primary color for current period bars
56
+ */
57
+ primaryColor?: string;
58
+
59
+ /**
60
+ * Secondary color for comparison period bars
61
+ */
62
+ secondaryColor?: string;
63
+
64
+ /**
65
+ * Formatter for values
66
+ */
67
+ valueFormatter?: ( value: number ) => string;
68
+
69
+ /**
70
+ * Formatter for delta values
71
+ */
72
+ deltaFormatter?: ( value: number ) => string;
73
+
74
+ /**
75
+ * Whether the chart is in loading state
76
+ */
77
+ loading?: boolean;
78
+
79
+ /**
80
+ * Additional CSS class name for the chart container
81
+ */
82
+ className?: string;
83
+
84
+ /**
85
+ * Custom styling for the chart container
86
+ */
87
+ style?: React.CSSProperties;
88
+ }
89
+
90
+ /**
91
+ * Default value formatter using formatMetricValue
92
+ *
93
+ * @param value - The numeric value to format
94
+ * @return Formatted string representation of the value
95
+ */
96
+ const defaultValueFormatter = ( value: number ): string => {
97
+ return formatMetricValue( value, 'number', {
98
+ useMultipliers: true,
99
+ decimals: 1,
100
+ } );
101
+ };
102
+
103
+ /**
104
+ * Default delta formatter using formatMetricValue
105
+ *
106
+ * @param value - The delta value to format
107
+ * @return Formatted percentage string
108
+ */
109
+ const defaultDeltaFormatter = ( value: number ): string => {
110
+ return formatMetricValue( value / 100, 'average', {
111
+ decimals: 0,
112
+ signDisplay: 'exceptZero',
113
+ } );
114
+ };
115
+
116
+ /**
117
+ * LeaderboardChart component displays a ranked list of data with progress bars
118
+ * and optional comparison values.
119
+ *
120
+ * @param props - Component props
121
+ * @param props.data - Array of leaderboard entries to display
122
+ * @param props.withComparison - Whether to show comparison data
123
+ * @param props.primaryColor - Primary color for current period bars
124
+ * @param props.secondaryColor - Secondary color for comparison period bars
125
+ * @param props.valueFormatter - Custom formatter for values
126
+ * @param props.deltaFormatter - Custom formatter for delta values
127
+ * @param props.loading - Whether the chart is in loading state
128
+ * @param props.className - Additional CSS class name
129
+ * @param props.style - Custom styling for the chart container
130
+ * @return JSX element representing the leaderboard chart
131
+ */
132
+ export const LeaderboardChart: FC< LeaderboardChartProps > = ( {
133
+ data,
134
+ withComparison = false,
135
+ primaryColor = '#3858E9',
136
+ secondaryColor = '#66BDFF',
137
+ valueFormatter = defaultValueFormatter,
138
+ deltaFormatter = defaultDeltaFormatter,
139
+ loading = false,
140
+ className,
141
+ style,
142
+ } ) => {
143
+ // TODO: Integrate with ThemeProvider:
144
+ // 1. Use theme.colors for primaryColor/secondaryColor defaults
145
+ // 2. Get delta sign colors from theme instead of hardcoding
146
+ // 3. Add useChartTheme() hook like other chart components
147
+ const signColors = [ '#D63638', '#757575', '#008A20' ];
148
+
149
+ const chartStyle = {
150
+ '--primary-color': primaryColor,
151
+ '--secondary-color': secondaryColor,
152
+ ...style,
153
+ } as React.CSSProperties;
154
+
155
+ // Handle empty or undefined data
156
+ if ( ! data || data.length === 0 ) {
157
+ return (
158
+ <div
159
+ className={ clsx( styles.leaderboardChart, loading && styles.loading, className ) }
160
+ style={ chartStyle }
161
+ >
162
+ <div className={ styles.emptyState }>{ loading ? 'Loading...' : 'No data available' }</div>
163
+ </div>
164
+ );
165
+ }
166
+
167
+ return (
168
+ <div
169
+ className={ clsx( styles.leaderboardChart, loading && styles.loading, className ) }
170
+ style={ chartStyle }
171
+ >
172
+ { data.map( entry => {
173
+ const colorIndex = Math.sign( entry.delta ) + 1;
174
+ const deltaColor = signColors[ colorIndex ];
175
+
176
+ return (
177
+ <div key={ entry.id } className={ styles.entryContainer }>
178
+ <div className={ styles.labelContainer }>
179
+ <span className={ styles.entryLabel }>{ entry.label }</span>
180
+
181
+ <div className={ styles.progressContainer }>
182
+ <ProgressBar
183
+ value={ entry.currentShare }
184
+ className={ clsx( styles.progressBar, styles.primaryBar ) }
185
+ />
186
+
187
+ { withComparison && (
188
+ <ProgressBar
189
+ value={ entry.previousShare }
190
+ className={ clsx( styles.progressBar, styles.secondaryBar ) }
191
+ />
192
+ ) }
193
+ </div>
194
+ </div>
195
+
196
+ <div className={ styles.valueContainer }>
197
+ <span className={ styles.currentValue }>
198
+ { valueFormatter( entry.currentValue ) }
199
+ </span>
200
+
201
+ { withComparison && (
202
+ <span className={ styles.deltaValue } style={ { color: deltaColor } }>
203
+ { deltaFormatter( entry.delta ) }
204
+ </span>
205
+ ) }
206
+ </div>
207
+ </div>
208
+ );
209
+ } ) }
210
+ </div>
211
+ );
212
+ };
213
+
214
+ export default LeaderboardChart;
@@ -0,0 +1,110 @@
1
+ import { Gridicon } from '@automattic/jetpack-components';
2
+ import clsx from 'clsx';
3
+ import { useEffect, useId, useRef, useState } from 'react';
4
+ import { isSafari } from '../shared/utils';
5
+ import styles from './line-chart.module.scss';
6
+ import type { ButtonWithPopover, PopoverElement, ToggleEvent } from '../../types';
7
+ import type { FC } from 'react';
8
+
9
+ export const POPOVER_BUTTON_SIZE = 44;
10
+
11
+ interface LineChartAnnotationLabelWithPopoverProps {
12
+ title: string;
13
+ subtitle?: string;
14
+ renderLabel: FC< { title: string; subtitle?: string } >;
15
+ renderLabelPopover: FC< { title: string; subtitle?: string } >;
16
+ }
17
+
18
+ const LineChartAnnotationLabelWithPopover: FC< LineChartAnnotationLabelWithPopoverProps > = ( {
19
+ title,
20
+ subtitle,
21
+ renderLabel,
22
+ renderLabelPopover,
23
+ } ) => {
24
+ const popoverId = useId();
25
+ const buttonRef = useRef< HTMLButtonElement >( null );
26
+ const popoverRef = useRef< HTMLDivElement >( null );
27
+ const [ isPositioned, setIsPositioned ] = useState( false );
28
+ const isBrowserSafari = isSafari();
29
+
30
+ useEffect( () => {
31
+ const button = buttonRef.current;
32
+ const popover = popoverRef.current;
33
+
34
+ if ( ! button || ! popover ) return;
35
+
36
+ const positionPopover = () => {
37
+ // Popover positioning in Safari is complicated due to issues with SVG foreign objects (https://bugs.webkit.org/show_bug.cgi?id=23113), so let it be positioned in the centre of the viewport.
38
+ if ( ! isBrowserSafari ) {
39
+ const buttonRect = button.getBoundingClientRect();
40
+ popover.style.left = `${ buttonRect.right }px`;
41
+ popover.style.top = `${ buttonRect.top }px`;
42
+ }
43
+
44
+ setIsPositioned( true );
45
+ };
46
+
47
+ // Position when popover shows
48
+ popover.addEventListener( 'toggle', ( e: ToggleEvent ) => {
49
+ if ( e.newState === 'open' ) {
50
+ positionPopover();
51
+ }
52
+ } );
53
+
54
+ // Initial positioning if already open
55
+ try {
56
+ if ( popover.matches( ':popover-open' ) ) {
57
+ positionPopover();
58
+ }
59
+ } catch {
60
+ // Ignore errors in test environments (e.g., JSDOM does not support :popover-open)
61
+ }
62
+ }, [ isBrowserSafari ] );
63
+
64
+ return (
65
+ <div className={ styles[ 'line-chart__annotation-label' ] }>
66
+ <button
67
+ ref={ buttonRef }
68
+ { ...( { popovertarget: popoverId } as ButtonWithPopover ) }
69
+ className={ styles[ 'line-chart__annotation-label-trigger-button' ] }
70
+ style={ {
71
+ width: `${ POPOVER_BUTTON_SIZE }px`,
72
+ height: `${ POPOVER_BUTTON_SIZE }px`,
73
+ transform: `translate(${ POPOVER_BUTTON_SIZE / 2 }px, 0)`,
74
+ } }
75
+ aria-label={ title || 'View details' }
76
+ >
77
+ { renderLabel( { title, subtitle } ) }
78
+ </button>
79
+ <div
80
+ ref={ popoverRef }
81
+ id={ popoverId }
82
+ { ...( { popover: 'auto' } as PopoverElement ) }
83
+ className={ clsx(
84
+ styles[ 'line-chart__annotation-label-popover' ],
85
+ isPositioned && styles[ 'line-chart__annotation-label-popover--visible' ],
86
+ isBrowserSafari && styles[ 'line-chart__annotation-label-popover--safari' ]
87
+ ) }
88
+ data-testid="line-chart-annotation-label-popover"
89
+ >
90
+ <div className={ styles[ 'line-chart__annotation-label-popover-header' ] }>
91
+ <div className={ styles[ 'line-chart__annotation-label-popover-content' ] }>
92
+ { renderLabelPopover( { title, subtitle } ) }
93
+ </div>
94
+ <button
95
+ { ...( {
96
+ popovertarget: popoverId,
97
+ popovertargetaction: 'hide',
98
+ } as ButtonWithPopover ) }
99
+ className={ styles[ 'line-chart__annotation-label-popover-close-button' ] }
100
+ aria-label="Close"
101
+ >
102
+ <Gridicon icon="cross" size={ 16 } />
103
+ </button>
104
+ </div>
105
+ </div>
106
+ </div>
107
+ );
108
+ };
109
+
110
+ export default LineChartAnnotationLabelWithPopover;
@@ -1,8 +1,19 @@
1
- import { Annotation, CircleSubject, Connector, Label, LineSubject } from '@visx/annotation';
1
+ import {
2
+ Annotation,
3
+ CircleSubject,
4
+ Connector,
5
+ HtmlLabel,
6
+ Label,
7
+ LineSubject,
8
+ } from '@visx/annotation';
2
9
  import { DataContext } from '@visx/xychart';
3
- import { merge } from 'lodash';
10
+ import merge from 'deepmerge';
4
11
  import { useContext, useRef, useEffect, useState, useMemo } from 'react';
5
12
  import { useChartTheme } from '../../providers/theme/theme-provider';
13
+ import { isSafari } from '../shared/utils';
14
+ import LineChartAnnotationLabelWithPopover, {
15
+ POPOVER_BUTTON_SIZE,
16
+ } from './line-chart-annotation-label-popover';
6
17
  import type { DataPointDate } from '../../types';
7
18
  import type { CircleSubjectProps } from '@visx/annotation/lib/components/CircleSubject';
8
19
  import type { ConnectorProps } from '@visx/annotation/lib/components/Connector';
@@ -15,7 +26,10 @@ export type AnnotationStyles = {
15
26
  circleSubject?: Omit< CircleSubjectProps, 'x' | 'y' > & { fill?: string };
16
27
  lineSubject?: Omit< LineSubjectProps, 'x' | 'y' >;
17
28
  connector?: Omit< ConnectorProps, 'x' | 'y' | 'dx' | 'dy' >;
18
- label?: Omit< LabelProps, 'title' | 'subtitle' >;
29
+ label?: Omit< LabelProps, 'title' | 'subtitle' | 'x' | 'y' > & {
30
+ x?: number | 'start' | 'end';
31
+ y?: number | 'start' | 'end';
32
+ };
19
33
  };
20
34
 
21
35
  type SubjectType = 'circle' | 'line-vertical' | 'line-horizontal';
@@ -30,6 +44,8 @@ export type LineChartAnnotationProps = {
30
44
  subjectType?: SubjectType;
31
45
  styles?: AnnotationStyles;
32
46
  testId?: string;
47
+ renderLabel?: FC< { title: string; subtitle?: string } >;
48
+ renderLabelPopover?: FC< { title: string; subtitle?: string } >;
33
49
  };
34
50
 
35
51
  export const getLabelPosition = ( {
@@ -79,6 +95,7 @@ export const getLabelPosition = ( {
79
95
 
80
96
  if ( effectiveX + annotationMaxWidth > xMax ) {
81
97
  isFlippedHorizontally = true;
98
+
82
99
  if ( subjectType === 'circle' ) {
83
100
  dx = -dx; // Just flip to the left side with same offset
84
101
  } else if ( subjectType === 'line-vertical' ) {
@@ -142,7 +159,7 @@ const getVerticalAnchor = (
142
159
  return y - height < yMax ? 'start' : 'end';
143
160
  }
144
161
 
145
- return 'middle';
162
+ return 'start';
146
163
  }
147
164
 
148
165
  return undefined;
@@ -155,6 +172,8 @@ const LineChartAnnotation: FC< LineChartAnnotationProps > = ( {
155
172
  subjectType = 'circle',
156
173
  styles: datumStyles,
157
174
  testId,
175
+ renderLabel,
176
+ renderLabelPopover,
158
177
  } ) => {
159
178
  const providerTheme = useChartTheme();
160
179
  const { xScale, yScale } = useContext( DataContext ) || {};
@@ -162,11 +181,11 @@ const LineChartAnnotation: FC< LineChartAnnotationProps > = ( {
162
181
  const [ height, setHeight ] = useState< number | null >( null );
163
182
 
164
183
  // Deep merge styles to preserve nested object properties
165
- const styles = merge( {}, providerTheme.annotationStyles, datumStyles );
184
+ const styles = merge( providerTheme.annotationStyles ?? {}, datumStyles ?? {} );
166
185
 
167
186
  // Measure the label height once after initial render
168
187
  useEffect( () => {
169
- if ( labelRef.current ) {
188
+ if ( labelRef.current?.getBBox ) {
170
189
  const bbox = labelRef.current.getBBox();
171
190
  setHeight( bbox.height );
172
191
  }
@@ -183,6 +202,22 @@ const LineChartAnnotation: FC< LineChartAnnotationProps > = ( {
183
202
  const [ yMin, yMax ] = yScale.range().map( Number );
184
203
  const [ xMin, xMax ] = xScale.range().map( Number );
185
204
 
205
+ // If a custom label is provided, use the provided position
206
+ if ( renderLabel ) {
207
+ return {
208
+ x,
209
+ dx: 0,
210
+ y,
211
+ dy: 0,
212
+ yMin,
213
+ yMax,
214
+ xMin,
215
+ xMax,
216
+ isFlippedHorizontally: false,
217
+ isFlippedVertically: false,
218
+ };
219
+ }
220
+
186
221
  const position = getLabelPosition( {
187
222
  subjectType,
188
223
  x,
@@ -195,13 +230,61 @@ const LineChartAnnotation: FC< LineChartAnnotationProps > = ( {
195
230
  } );
196
231
 
197
232
  return { x, y, yMin, yMax, xMin, xMax, ...position };
198
- }, [ datum, xScale, yScale, subjectType, styles?.label?.maxWidth, height ] );
233
+ }, [ datum, xScale, yScale, subjectType, styles?.label?.maxWidth, height, renderLabel ] );
199
234
 
200
235
  if ( ! positionData ) return null;
201
236
 
202
237
  const { x, y, yMin, yMax, xMin, xMax, dx, dy, isFlippedHorizontally, isFlippedVertically } =
203
238
  positionData;
204
239
 
240
+ const getLabelY = () => {
241
+ const labelY = styles?.label?.y;
242
+
243
+ if ( labelY === 'start' ) return yMax;
244
+ if ( labelY === 'end' ) return yMin;
245
+
246
+ return labelY;
247
+ };
248
+
249
+ const getLabelX = () => {
250
+ const labelX = styles?.label?.x;
251
+
252
+ if ( labelX === 'start' ) return xMin;
253
+ if ( labelX === 'end' ) return xMax;
254
+
255
+ return labelX;
256
+ };
257
+
258
+ const labelPosition = {
259
+ x: getLabelX(),
260
+ y: getLabelY(),
261
+ };
262
+
263
+ // Safari has a bug where children of an SVG foreignObject are not positioned correctly https://bugs.webkit.org/show_bug.cgi?id=23113
264
+ // This is a workaround to position the label correctly
265
+ const getSafariHTMLLabelPosition = () => {
266
+ const labelWidth = POPOVER_BUTTON_SIZE;
267
+ const labelHeight = POPOVER_BUTTON_SIZE;
268
+
269
+ return isSafari()
270
+ ? {
271
+ transform: `translate(${
272
+ x +
273
+ ( dx || 0 ) +
274
+ ( typeof labelPosition.x === 'number' ? labelPosition.x - x : 0 ) -
275
+ labelWidth
276
+ }px, ${
277
+ y +
278
+ ( dy || 0 ) +
279
+ ( typeof labelPosition.y === 'number' ? labelPosition.y - y : 0 ) -
280
+ labelHeight
281
+ }px)`,
282
+ width: labelWidth,
283
+ height: labelHeight,
284
+ }
285
+ : undefined;
286
+ };
287
+
205
288
  return (
206
289
  <g data-testid={ testId }>
207
290
  <Annotation x={ x } y={ y } dx={ dx } dy={ dy }>
@@ -221,21 +304,39 @@ const LineChartAnnotation: FC< LineChartAnnotationProps > = ( {
221
304
  { ...{ ...styles?.lineSubject, orientation: 'horizontal' } }
222
305
  />
223
306
  ) }
224
- <g ref={ labelRef }>
225
- <Label
226
- title={ title }
227
- subtitle={ subtitle }
228
- { ...styles?.label }
229
- horizontalAnchor={ getHorizontalAnchor( subjectType, isFlippedHorizontally ) }
230
- verticalAnchor={ getVerticalAnchor(
231
- subjectType,
232
- isFlippedVertically,
233
- y,
234
- yMax,
235
- height ?? ANNOTATION_INIT_HEIGHT
236
- ) }
237
- />
238
- </g>
307
+ { renderLabel ? (
308
+ <HtmlLabel { ...styles?.label } { ...labelPosition }>
309
+ <div style={ getSafariHTMLLabelPosition() }>
310
+ { renderLabelPopover ? (
311
+ <LineChartAnnotationLabelWithPopover
312
+ title={ title }
313
+ subtitle={ subtitle }
314
+ renderLabel={ renderLabel }
315
+ renderLabelPopover={ renderLabelPopover }
316
+ />
317
+ ) : (
318
+ renderLabel( { title, subtitle } )
319
+ ) }
320
+ </div>
321
+ </HtmlLabel>
322
+ ) : (
323
+ <g ref={ labelRef }>
324
+ <Label
325
+ title={ title }
326
+ subtitle={ subtitle }
327
+ { ...styles?.label }
328
+ { ...labelPosition }
329
+ horizontalAnchor={ getHorizontalAnchor( subjectType, isFlippedHorizontally ) }
330
+ verticalAnchor={ getVerticalAnchor(
331
+ subjectType,
332
+ isFlippedVertically,
333
+ y,
334
+ yMax,
335
+ height ?? ANNOTATION_INIT_HEIGHT
336
+ ) }
337
+ />
338
+ </g>
339
+ ) }
239
340
  </Annotation>
240
341
  </g>
241
342
  );
@@ -0,0 +1,135 @@
1
+ import { DataContext } from '@visx/xychart';
2
+ import { useEffect, useState, useCallback } from 'react';
3
+ import { useLineChartContext } from './line-chart-context';
4
+ import styles from './line-chart.module.scss';
5
+ import type { AxisScale } from '@visx/axis';
6
+ import type { FC, ReactNode } from 'react';
7
+
8
+ export interface LineChartAnnotationsProps {
9
+ children?: ReactNode;
10
+ }
11
+
12
+ interface ScaleData {
13
+ xScale: AxisScale< Date >;
14
+ yScale: AxisScale< number >;
15
+ }
16
+
17
+ const LineChartAnnotationsOverlay: FC< LineChartAnnotationsProps > = ( { children } ) => {
18
+ const { chartRef, chartWidth, chartHeight } = useLineChartContext();
19
+
20
+ const [ scales, setScales ] = useState< ScaleData | null >( null );
21
+ const [ scalesStable, setScalesStable ] = useState< boolean >( false );
22
+
23
+ // Create a signature for scale data to enable easy comparison
24
+ const createScaleSignature = useCallback( ( scaleData: ScaleData ) => {
25
+ const xDomain = scaleData.xScale.domain();
26
+ const yDomain = scaleData.yScale.domain();
27
+ const xRange = scaleData.xScale.range();
28
+ const yRange = scaleData.yScale.range();
29
+
30
+ return `${ xDomain.join( ',' ) }-${ yDomain.join( ',' ) }-${ xRange.join(
31
+ ','
32
+ ) }-${ yRange.join( ',' ) }`;
33
+ }, [] );
34
+
35
+ // Get scales from chart ref and return them with signature for comparison
36
+ const getScalesData = useCallback( () => {
37
+ if ( chartRef?.current ) {
38
+ const scaleData = chartRef.current.getScales();
39
+
40
+ if ( scaleData ) {
41
+ const scaleInfo = {
42
+ xScale: scaleData.xScale as AxisScale< Date >,
43
+ yScale: scaleData.yScale as AxisScale< number >,
44
+ };
45
+
46
+ return {
47
+ scales: scaleInfo,
48
+ signature: createScaleSignature( scaleInfo ),
49
+ };
50
+ }
51
+ }
52
+
53
+ return null;
54
+ }, [ chartRef, createScaleSignature ] );
55
+
56
+ // The chart resizes on render so we need to monitor the scales until they stabilize
57
+ useEffect( () => {
58
+ let timeoutId: number | null = null;
59
+ let lastSignature: string | null = null;
60
+ let retryCount = 0;
61
+ const maxRetries = 20; // 20 * 50ms = 1 second max
62
+ const checkInterval = 50; // Check every 50ms
63
+
64
+ // Reset stability state when monitoring starts
65
+ setScalesStable( false );
66
+
67
+ const monitorScales = () => {
68
+ const currentScaleData = getScalesData();
69
+
70
+ // If we got scales, compare signatures
71
+ if ( currentScaleData ) {
72
+ // Check if scales have settled by comparing signatures
73
+ const scalesSettled = lastSignature && currentScaleData.signature === lastSignature;
74
+
75
+ if ( scalesSettled ) {
76
+ // Scales have stabilized, mark as stable
77
+ setScalesStable( true );
78
+ return;
79
+ }
80
+
81
+ // Update scales and remember signature for next comparison
82
+ setScales( currentScaleData.scales );
83
+ lastSignature = currentScaleData.signature;
84
+ }
85
+
86
+ // Continue monitoring if we haven't exceeded max retries
87
+ if ( retryCount < maxRetries ) {
88
+ retryCount++;
89
+ timeoutId = setTimeout( monitorScales, checkInterval ) as unknown as number;
90
+ }
91
+ };
92
+
93
+ monitorScales();
94
+
95
+ return () => {
96
+ if ( timeoutId ) {
97
+ clearTimeout( timeoutId );
98
+ }
99
+ };
100
+ }, [ getScalesData, chartWidth, chartHeight ] );
101
+
102
+ // Early return if no chart data available
103
+ if ( ! chartRef || ! children ) {
104
+ return null;
105
+ }
106
+
107
+ if ( ! scales || ! scalesStable ) {
108
+ return null;
109
+ }
110
+
111
+ // Create a DataContext value that mimics what visx provides
112
+ // We're intentionally providing minimal context for annotations to work
113
+ const dataContextValue = {
114
+ xScale: scales.xScale,
115
+ yScale: scales.yScale,
116
+ margin: { top: 0, right: 0, bottom: 0, left: 0 },
117
+ width: chartWidth,
118
+ height: chartHeight,
119
+ } as unknown as Parameters< typeof DataContext.Provider >[ 0 ][ 'value' ];
120
+
121
+ return (
122
+ <DataContext.Provider value={ dataContextValue }>
123
+ <svg
124
+ width={ chartWidth }
125
+ height={ chartHeight }
126
+ className={ styles[ 'line-chart__annotations-overlay' ] }
127
+ data-testid="line-chart-annotations-overlay"
128
+ >
129
+ { children }
130
+ </svg>
131
+ </DataContext.Provider>
132
+ );
133
+ };
134
+
135
+ export default LineChartAnnotationsOverlay;
@@ -0,0 +1,28 @@
1
+ import { createContext, useContext } from 'react';
2
+
3
+ export interface LineChartRef {
4
+ getScales: () => { xScale: unknown; yScale: unknown } | null;
5
+ getChartDimensions: () => {
6
+ width: number;
7
+ height: number;
8
+ margin: { top?: number; right?: number; bottom?: number; left?: number };
9
+ };
10
+ }
11
+
12
+ // Local context for LineChart implicit state sharing
13
+ export interface LineChartContextValue {
14
+ chartId: string;
15
+ chartRef: React.RefObject< LineChartRef >;
16
+ chartWidth: number;
17
+ chartHeight: number;
18
+ }
19
+
20
+ export const LineChartContext = createContext< LineChartContextValue | null >( null );
21
+
22
+ export const useLineChartContext = (): LineChartContextValue => {
23
+ const context = useContext( LineChartContext );
24
+ if ( ! context ) {
25
+ throw new Error( 'useLineChartContext must be used within a LineChart component' );
26
+ }
27
+ return context;
28
+ };