@fluentui/react-charts 0.0.0-nightly-20251106-0410.1 → 0.0.0-nightly-20251110-0407.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. package/CHANGELOG.md +31 -13
  2. package/dist/index.d.ts +213 -2
  3. package/lib/AnnotationOnlyChart.js +1 -0
  4. package/lib/AnnotationOnlyChart.js.map +1 -0
  5. package/lib/components/AnnotationOnlyChart/AnnotationOnlyChart.js +208 -0
  6. package/lib/components/AnnotationOnlyChart/AnnotationOnlyChart.js.map +1 -0
  7. package/lib/components/AnnotationOnlyChart/AnnotationOnlyChart.types.js +1 -0
  8. package/lib/components/AnnotationOnlyChart/AnnotationOnlyChart.types.js.map +1 -0
  9. package/lib/components/AnnotationOnlyChart/index.js +2 -0
  10. package/lib/components/AnnotationOnlyChart/index.js.map +1 -0
  11. package/lib/components/AnnotationOnlyChart/useAnnotationOnlyChartStyles.styles.js +31 -0
  12. package/lib/components/AnnotationOnlyChart/useAnnotationOnlyChartStyles.styles.js.map +1 -0
  13. package/lib/components/AnnotationOnlyChart/useAnnotationOnlyChartStyles.styles.raw.js +23 -0
  14. package/lib/components/AnnotationOnlyChart/useAnnotationOnlyChartStyles.styles.raw.js.map +1 -0
  15. package/lib/components/AreaChart/useAreaChartStyles.styles.js +3 -1
  16. package/lib/components/AreaChart/useAreaChartStyles.styles.js.map +1 -1
  17. package/lib/components/AreaChart/useAreaChartStyles.styles.raw.js +3 -1
  18. package/lib/components/AreaChart/useAreaChartStyles.styles.raw.js.map +1 -1
  19. package/lib/components/ChartTable/ChartTable.js +3 -1
  20. package/lib/components/ChartTable/ChartTable.js.map +1 -1
  21. package/lib/components/CommonComponents/Annotations/ChartAnnotationLayer.js +617 -0
  22. package/lib/components/CommonComponents/Annotations/ChartAnnotationLayer.js.map +1 -0
  23. package/lib/components/CommonComponents/Annotations/ChartAnnotationLayer.types.js +1 -0
  24. package/lib/components/CommonComponents/Annotations/ChartAnnotationLayer.types.js.map +1 -0
  25. package/lib/components/CommonComponents/Annotations/index.js +2 -0
  26. package/lib/components/CommonComponents/Annotations/index.js.map +1 -0
  27. package/lib/components/CommonComponents/Annotations/useChartAnnotationLayer.styles.js +173 -0
  28. package/lib/components/CommonComponents/Annotations/useChartAnnotationLayer.styles.js.map +1 -0
  29. package/lib/components/CommonComponents/Annotations/useChartAnnotationLayer.styles.raw.js +126 -0
  30. package/lib/components/CommonComponents/Annotations/useChartAnnotationLayer.styles.raw.js.map +1 -0
  31. package/lib/components/CommonComponents/CartesianChart.js +56 -27
  32. package/lib/components/CommonComponents/CartesianChart.js.map +1 -1
  33. package/lib/components/CommonComponents/CartesianChart.types.js.map +1 -1
  34. package/lib/components/CommonComponents/index.js +2 -0
  35. package/lib/components/CommonComponents/index.js.map +1 -1
  36. package/lib/components/CommonComponents/useCartesianChartStyles.styles.js +17 -4
  37. package/lib/components/CommonComponents/useCartesianChartStyles.styles.js.map +1 -1
  38. package/lib/components/CommonComponents/useCartesianChartStyles.styles.raw.js +14 -1
  39. package/lib/components/CommonComponents/useCartesianChartStyles.styles.raw.js.map +1 -1
  40. package/lib/components/DeclarativeChart/DeclarativeChart.js +39 -19
  41. package/lib/components/DeclarativeChart/DeclarativeChart.js.map +1 -1
  42. package/lib/components/DeclarativeChart/PlotlyColorAdapter.js.map +1 -1
  43. package/lib/components/DeclarativeChart/PlotlySchemaAdapter.js +571 -6
  44. package/lib/components/DeclarativeChart/PlotlySchemaAdapter.js.map +1 -1
  45. package/lib/components/DonutChart/DonutChart.js +12 -7
  46. package/lib/components/DonutChart/DonutChart.js.map +1 -1
  47. package/lib/components/FunnelChart/FunnelChart.js +5 -5
  48. package/lib/components/FunnelChart/FunnelChart.js.map +1 -1
  49. package/lib/components/GanttChart/useGanttChartStyles.styles.js +3 -1
  50. package/lib/components/GanttChart/useGanttChartStyles.styles.js.map +1 -1
  51. package/lib/components/GanttChart/useGanttChartStyles.styles.raw.js +3 -1
  52. package/lib/components/GanttChart/useGanttChartStyles.styles.raw.js.map +1 -1
  53. package/lib/components/GaugeChart/GaugeChart.js +3 -1
  54. package/lib/components/GaugeChart/GaugeChart.js.map +1 -1
  55. package/lib/components/GroupedVerticalBarChart/useGroupedVerticalBarChartStyles.styles.js +3 -1
  56. package/lib/components/GroupedVerticalBarChart/useGroupedVerticalBarChartStyles.styles.js.map +1 -1
  57. package/lib/components/GroupedVerticalBarChart/useGroupedVerticalBarChartStyles.styles.raw.js +3 -1
  58. package/lib/components/GroupedVerticalBarChart/useGroupedVerticalBarChartStyles.styles.raw.js.map +1 -1
  59. package/lib/components/HeatMapChart/HeatMapChart.js +5 -5
  60. package/lib/components/HeatMapChart/HeatMapChart.js.map +1 -1
  61. package/lib/components/HeatMapChart/useHeatMapChartStyles.styles.js +3 -1
  62. package/lib/components/HeatMapChart/useHeatMapChartStyles.styles.js.map +1 -1
  63. package/lib/components/HeatMapChart/useHeatMapChartStyles.styles.raw.js +3 -1
  64. package/lib/components/HeatMapChart/useHeatMapChartStyles.styles.raw.js.map +1 -1
  65. package/lib/components/HorizontalBarChart/HorizontalBarChart.js +3 -1
  66. package/lib/components/HorizontalBarChart/HorizontalBarChart.js.map +1 -1
  67. package/lib/components/HorizontalBarChartWithAxis/useHorizontalBarChartWithAxisStyles.styles.js +3 -1
  68. package/lib/components/HorizontalBarChartWithAxis/useHorizontalBarChartWithAxisStyles.styles.js.map +1 -1
  69. package/lib/components/HorizontalBarChartWithAxis/useHorizontalBarChartWithAxisStyles.styles.raw.js +3 -1
  70. package/lib/components/HorizontalBarChartWithAxis/useHorizontalBarChartWithAxisStyles.styles.raw.js.map +1 -1
  71. package/lib/components/Legends/Legends.js +3 -1
  72. package/lib/components/Legends/Legends.js.map +1 -1
  73. package/lib/components/Legends/Legends.types.js.map +1 -1
  74. package/lib/components/LineChart/LineChart.js +5 -4
  75. package/lib/components/LineChart/LineChart.js.map +1 -1
  76. package/lib/components/LineChart/eventAnnotation/Textbox.js.map +1 -1
  77. package/lib/components/LineChart/useLineChartStyles.styles.js +3 -1
  78. package/lib/components/LineChart/useLineChartStyles.styles.js.map +1 -1
  79. package/lib/components/LineChart/useLineChartStyles.styles.raw.js +3 -1
  80. package/lib/components/LineChart/useLineChartStyles.styles.raw.js.map +1 -1
  81. package/lib/components/ResponsiveContainer/ResponsiveContainer.js +1 -1
  82. package/lib/components/ResponsiveContainer/ResponsiveContainer.js.map +1 -1
  83. package/lib/components/SankeyChart/SankeyChart.js +1 -1
  84. package/lib/components/SankeyChart/SankeyChart.js.map +1 -1
  85. package/lib/components/ScatterChart/useScatterChartStyles.styles.js +3 -1
  86. package/lib/components/ScatterChart/useScatterChartStyles.styles.js.map +1 -1
  87. package/lib/components/ScatterChart/useScatterChartStyles.styles.raw.js +3 -1
  88. package/lib/components/ScatterChart/useScatterChartStyles.styles.raw.js.map +1 -1
  89. package/lib/components/VerticalBarChart/VerticalBarChart.js +3 -1
  90. package/lib/components/VerticalBarChart/VerticalBarChart.js.map +1 -1
  91. package/lib/components/VerticalBarChart/useVerticalBarChartStyles.styles.js +3 -1
  92. package/lib/components/VerticalBarChart/useVerticalBarChartStyles.styles.js.map +1 -1
  93. package/lib/components/VerticalBarChart/useVerticalBarChartStyles.styles.raw.js +3 -1
  94. package/lib/components/VerticalBarChart/useVerticalBarChartStyles.styles.raw.js.map +1 -1
  95. package/lib/components/VerticalStackedBarChart/VerticalStackedBarChart.js +12 -4
  96. package/lib/components/VerticalStackedBarChart/VerticalStackedBarChart.js.map +1 -1
  97. package/lib/components/VerticalStackedBarChart/useVerticalStackedBarChartStyles.styles.js +3 -1
  98. package/lib/components/VerticalStackedBarChart/useVerticalStackedBarChartStyles.styles.js.map +1 -1
  99. package/lib/components/VerticalStackedBarChart/useVerticalStackedBarChartStyles.styles.raw.js +3 -1
  100. package/lib/components/VerticalStackedBarChart/useVerticalStackedBarChartStyles.styles.raw.js.map +1 -1
  101. package/lib/index.js +1 -0
  102. package/lib/index.js.map +1 -1
  103. package/lib/types/ChartAnnotation.js +1 -0
  104. package/lib/types/ChartAnnotation.js.map +1 -0
  105. package/lib/types/index.js +1 -0
  106. package/lib/types/index.js.map +1 -1
  107. package/lib/utilities/FocusableTooltipText.js +1 -1
  108. package/lib/utilities/FocusableTooltipText.js.map +1 -1
  109. package/lib/utilities/SVGTooltipText.js +8 -8
  110. package/lib/utilities/SVGTooltipText.js.map +1 -1
  111. package/lib/utilities/image-export-utils.js +108 -0
  112. package/lib/utilities/image-export-utils.js.map +1 -1
  113. package/lib-commonjs/AnnotationOnlyChart.js +6 -0
  114. package/lib-commonjs/AnnotationOnlyChart.js.map +1 -0
  115. package/lib-commonjs/components/AnnotationOnlyChart/AnnotationOnlyChart.js +219 -0
  116. package/lib-commonjs/components/AnnotationOnlyChart/AnnotationOnlyChart.js.map +1 -0
  117. package/lib-commonjs/components/AnnotationOnlyChart/AnnotationOnlyChart.types.js +6 -0
  118. package/lib-commonjs/components/AnnotationOnlyChart/AnnotationOnlyChart.types.js.map +1 -0
  119. package/lib-commonjs/components/AnnotationOnlyChart/index.js +7 -0
  120. package/lib-commonjs/components/AnnotationOnlyChart/index.js.map +1 -0
  121. package/lib-commonjs/components/AnnotationOnlyChart/useAnnotationOnlyChartStyles.styles.js +56 -0
  122. package/lib-commonjs/components/AnnotationOnlyChart/useAnnotationOnlyChartStyles.styles.js.map +1 -0
  123. package/lib-commonjs/components/AnnotationOnlyChart/useAnnotationOnlyChartStyles.styles.raw.js +33 -0
  124. package/lib-commonjs/components/AnnotationOnlyChart/useAnnotationOnlyChartStyles.styles.raw.js.map +1 -0
  125. package/lib-commonjs/components/AreaChart/useAreaChartStyles.styles.js +3 -1
  126. package/lib-commonjs/components/AreaChart/useAreaChartStyles.styles.js.map +1 -1
  127. package/lib-commonjs/components/AreaChart/useAreaChartStyles.styles.raw.js +3 -1
  128. package/lib-commonjs/components/AreaChart/useAreaChartStyles.styles.raw.js.map +1 -1
  129. package/lib-commonjs/components/ChartTable/ChartTable.js +3 -1
  130. package/lib-commonjs/components/ChartTable/ChartTable.js.map +1 -1
  131. package/lib-commonjs/components/CommonComponents/Annotations/ChartAnnotationLayer.js +628 -0
  132. package/lib-commonjs/components/CommonComponents/Annotations/ChartAnnotationLayer.js.map +1 -0
  133. package/lib-commonjs/components/CommonComponents/Annotations/ChartAnnotationLayer.types.js +4 -0
  134. package/lib-commonjs/components/CommonComponents/Annotations/ChartAnnotationLayer.types.js.map +1 -0
  135. package/lib-commonjs/components/CommonComponents/Annotations/index.js +7 -0
  136. package/lib-commonjs/components/CommonComponents/Annotations/index.js.map +1 -0
  137. package/lib-commonjs/components/CommonComponents/Annotations/useChartAnnotationLayer.styles.js +265 -0
  138. package/lib-commonjs/components/CommonComponents/Annotations/useChartAnnotationLayer.styles.js.map +1 -0
  139. package/lib-commonjs/components/CommonComponents/Annotations/useChartAnnotationLayer.styles.raw.js +161 -0
  140. package/lib-commonjs/components/CommonComponents/Annotations/useChartAnnotationLayer.styles.raw.js.map +1 -0
  141. package/lib-commonjs/components/CommonComponents/CartesianChart.js +56 -27
  142. package/lib-commonjs/components/CommonComponents/CartesianChart.js.map +1 -1
  143. package/lib-commonjs/components/CommonComponents/CartesianChart.types.js.map +1 -1
  144. package/lib-commonjs/components/CommonComponents/index.js +2 -0
  145. package/lib-commonjs/components/CommonComponents/index.js.map +1 -1
  146. package/lib-commonjs/components/CommonComponents/useCartesianChartStyles.styles.js +16 -2
  147. package/lib-commonjs/components/CommonComponents/useCartesianChartStyles.styles.js.map +1 -1
  148. package/lib-commonjs/components/CommonComponents/useCartesianChartStyles.styles.raw.js +14 -1
  149. package/lib-commonjs/components/CommonComponents/useCartesianChartStyles.styles.raw.js.map +1 -1
  150. package/lib-commonjs/components/DeclarativeChart/DeclarativeChart.js +38 -18
  151. package/lib-commonjs/components/DeclarativeChart/DeclarativeChart.js.map +1 -1
  152. package/lib-commonjs/components/DeclarativeChart/PlotlyColorAdapter.js.map +1 -1
  153. package/lib-commonjs/components/DeclarativeChart/PlotlySchemaAdapter.js +574 -6
  154. package/lib-commonjs/components/DeclarativeChart/PlotlySchemaAdapter.js.map +1 -1
  155. package/lib-commonjs/components/DonutChart/DonutChart.js +12 -7
  156. package/lib-commonjs/components/DonutChart/DonutChart.js.map +1 -1
  157. package/lib-commonjs/components/FunnelChart/FunnelChart.js +5 -5
  158. package/lib-commonjs/components/FunnelChart/FunnelChart.js.map +1 -1
  159. package/lib-commonjs/components/GanttChart/useGanttChartStyles.styles.js +3 -1
  160. package/lib-commonjs/components/GanttChart/useGanttChartStyles.styles.js.map +1 -1
  161. package/lib-commonjs/components/GanttChart/useGanttChartStyles.styles.raw.js +3 -1
  162. package/lib-commonjs/components/GanttChart/useGanttChartStyles.styles.raw.js.map +1 -1
  163. package/lib-commonjs/components/GaugeChart/GaugeChart.js +3 -1
  164. package/lib-commonjs/components/GaugeChart/GaugeChart.js.map +1 -1
  165. package/lib-commonjs/components/GroupedVerticalBarChart/useGroupedVerticalBarChartStyles.styles.js +3 -1
  166. package/lib-commonjs/components/GroupedVerticalBarChart/useGroupedVerticalBarChartStyles.styles.js.map +1 -1
  167. package/lib-commonjs/components/GroupedVerticalBarChart/useGroupedVerticalBarChartStyles.styles.raw.js +3 -1
  168. package/lib-commonjs/components/GroupedVerticalBarChart/useGroupedVerticalBarChartStyles.styles.raw.js.map +1 -1
  169. package/lib-commonjs/components/HeatMapChart/HeatMapChart.js +5 -5
  170. package/lib-commonjs/components/HeatMapChart/HeatMapChart.js.map +1 -1
  171. package/lib-commonjs/components/HeatMapChart/useHeatMapChartStyles.styles.js +3 -1
  172. package/lib-commonjs/components/HeatMapChart/useHeatMapChartStyles.styles.js.map +1 -1
  173. package/lib-commonjs/components/HeatMapChart/useHeatMapChartStyles.styles.raw.js +3 -1
  174. package/lib-commonjs/components/HeatMapChart/useHeatMapChartStyles.styles.raw.js.map +1 -1
  175. package/lib-commonjs/components/HorizontalBarChart/HorizontalBarChart.js +3 -1
  176. package/lib-commonjs/components/HorizontalBarChart/HorizontalBarChart.js.map +1 -1
  177. package/lib-commonjs/components/HorizontalBarChartWithAxis/useHorizontalBarChartWithAxisStyles.styles.js +3 -1
  178. package/lib-commonjs/components/HorizontalBarChartWithAxis/useHorizontalBarChartWithAxisStyles.styles.js.map +1 -1
  179. package/lib-commonjs/components/HorizontalBarChartWithAxis/useHorizontalBarChartWithAxisStyles.styles.raw.js +3 -1
  180. package/lib-commonjs/components/HorizontalBarChartWithAxis/useHorizontalBarChartWithAxisStyles.styles.raw.js.map +1 -1
  181. package/lib-commonjs/components/Legends/Legends.js +3 -1
  182. package/lib-commonjs/components/Legends/Legends.js.map +1 -1
  183. package/lib-commonjs/components/Legends/Legends.types.js.map +1 -1
  184. package/lib-commonjs/components/LineChart/LineChart.js +5 -4
  185. package/lib-commonjs/components/LineChart/LineChart.js.map +1 -1
  186. package/lib-commonjs/components/LineChart/eventAnnotation/Textbox.js.map +1 -1
  187. package/lib-commonjs/components/LineChart/useLineChartStyles.styles.js +3 -1
  188. package/lib-commonjs/components/LineChart/useLineChartStyles.styles.js.map +1 -1
  189. package/lib-commonjs/components/LineChart/useLineChartStyles.styles.raw.js +3 -1
  190. package/lib-commonjs/components/LineChart/useLineChartStyles.styles.raw.js.map +1 -1
  191. package/lib-commonjs/components/ResponsiveContainer/ResponsiveContainer.js +1 -1
  192. package/lib-commonjs/components/ResponsiveContainer/ResponsiveContainer.js.map +1 -1
  193. package/lib-commonjs/components/SankeyChart/SankeyChart.js +1 -1
  194. package/lib-commonjs/components/SankeyChart/SankeyChart.js.map +1 -1
  195. package/lib-commonjs/components/ScatterChart/useScatterChartStyles.styles.js +3 -1
  196. package/lib-commonjs/components/ScatterChart/useScatterChartStyles.styles.js.map +1 -1
  197. package/lib-commonjs/components/ScatterChart/useScatterChartStyles.styles.raw.js +3 -1
  198. package/lib-commonjs/components/ScatterChart/useScatterChartStyles.styles.raw.js.map +1 -1
  199. package/lib-commonjs/components/VerticalBarChart/VerticalBarChart.js +3 -1
  200. package/lib-commonjs/components/VerticalBarChart/VerticalBarChart.js.map +1 -1
  201. package/lib-commonjs/components/VerticalBarChart/useVerticalBarChartStyles.styles.js +3 -1
  202. package/lib-commonjs/components/VerticalBarChart/useVerticalBarChartStyles.styles.js.map +1 -1
  203. package/lib-commonjs/components/VerticalBarChart/useVerticalBarChartStyles.styles.raw.js +3 -1
  204. package/lib-commonjs/components/VerticalBarChart/useVerticalBarChartStyles.styles.raw.js.map +1 -1
  205. package/lib-commonjs/components/VerticalStackedBarChart/VerticalStackedBarChart.js +12 -4
  206. package/lib-commonjs/components/VerticalStackedBarChart/VerticalStackedBarChart.js.map +1 -1
  207. package/lib-commonjs/components/VerticalStackedBarChart/useVerticalStackedBarChartStyles.styles.js +3 -1
  208. package/lib-commonjs/components/VerticalStackedBarChart/useVerticalStackedBarChartStyles.styles.js.map +1 -1
  209. package/lib-commonjs/components/VerticalStackedBarChart/useVerticalStackedBarChartStyles.styles.raw.js +3 -1
  210. package/lib-commonjs/components/VerticalStackedBarChart/useVerticalStackedBarChartStyles.styles.raw.js.map +1 -1
  211. package/lib-commonjs/index.js +1 -0
  212. package/lib-commonjs/index.js.map +1 -1
  213. package/lib-commonjs/types/ChartAnnotation.js +6 -0
  214. package/lib-commonjs/types/ChartAnnotation.js.map +1 -0
  215. package/lib-commonjs/types/index.js +1 -0
  216. package/lib-commonjs/types/index.js.map +1 -1
  217. package/lib-commonjs/utilities/FocusableTooltipText.js +1 -1
  218. package/lib-commonjs/utilities/FocusableTooltipText.js.map +1 -1
  219. package/lib-commonjs/utilities/SVGTooltipText.js +8 -8
  220. package/lib-commonjs/utilities/SVGTooltipText.js.map +1 -1
  221. package/lib-commonjs/utilities/image-export-utils.js +108 -0
  222. package/lib-commonjs/utilities/image-export-utils.js.map +1 -1
  223. package/package.json +12 -12
@@ -9,7 +9,7 @@ export const FocusableTooltipText = /*#__PURE__*/ React.forwardRef((props, forwa
9
9
  const [textOverflow, setTextOverflow] = useState(false);
10
10
  const tooltipChild = useRef(null);
11
11
  const async = useRef(new Async()).current;
12
- const resizeObserver = useRef();
12
+ const resizeObserver = useRef(undefined);
13
13
  const getTargetElement = useCallback(()=>{
14
14
  if (!tooltipChild.current || !tooltipChild.current.parentElement) {
15
15
  return undefined;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utilities/FocusableTooltipText.tsx"],"sourcesContent":["'use client';\n\n/* eslint-disable no-restricted-globals */\nimport * as React from 'react';\nimport { useCallback, useState, useEffect, useRef } from 'react';\nimport { Tooltip } from '@fluentui/react-tooltip';\nimport type { JSXElement } from '@fluentui/react-utilities';\nimport { hasOverflow } from './overflow-utils';\nimport { getAccessibleDataObject } from './index';\nimport { AccessibilityProps } from '../types/index';\nimport { Async } from './async-utils';\n\ninterface IFocusableTooltipTextProps {\n className?: string;\n content:\n | string\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n | JSXElement\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n | JSXElement[];\n accessibilityData?: AccessibilityProps;\n}\n\nexport const FocusableTooltipText: React.FunctionComponent<IFocusableTooltipTextProps> = React.forwardRef<\n HTMLDivElement,\n IFocusableTooltipTextProps\n>((props, forwardedRef) => {\n const [textOverflow, setTextOverflow] = useState(false);\n const tooltipChild = useRef<HTMLSpanElement>(null);\n const async = useRef(new Async()).current;\n const resizeObserver = useRef<ResizeObserver>();\n\n const getTargetElement = useCallback((): HTMLElement | undefined => {\n if (!tooltipChild.current || !tooltipChild.current.parentElement) {\n return undefined;\n }\n return tooltipChild.current.parentElement;\n }, [tooltipChild]);\n\n const checkTextOverflow = useCallback(() => {\n const overflowElement = getTargetElement();\n const isTextOverflow = !!overflowElement && hasOverflow(overflowElement);\n if (isTextOverflow !== textOverflow) {\n setTextOverflow(isTextOverflow);\n }\n }, [getTargetElement, textOverflow, setTextOverflow]);\n\n useEffect(() => {\n checkTextOverflow();\n }, [checkTextOverflow]);\n\n useEffect(() => {\n // setup part executed only when the component mounts/updates\n const overflowElement = getTargetElement();\n if (window.ResizeObserver && overflowElement) {\n resizeObserver.current = new window.ResizeObserver(async.debounce(checkTextOverflow, 500));\n resizeObserver.current.observe(overflowElement);\n }\n // cleanup part executed only when the component unmounts\n return () => {\n resizeObserver.current?.disconnect();\n async.dispose();\n };\n }, [async, checkTextOverflow, getTargetElement]);\n\n return (\n <div className={props.className}>\n <Tooltip content={props.content} relationship=\"description\">\n <span {...getAccessibleDataObject(props.accessibilityData)} ref={tooltipChild} data-is-focusable={textOverflow}>\n {props.content}\n </span>\n </Tooltip>\n </div>\n );\n});\n"],"names":["React","useCallback","useState","useEffect","useRef","Tooltip","hasOverflow","getAccessibleDataObject","Async","FocusableTooltipText","forwardRef","props","forwardedRef","textOverflow","setTextOverflow","tooltipChild","async","current","resizeObserver","getTargetElement","parentElement","undefined","checkTextOverflow","overflowElement","isTextOverflow","window","ResizeObserver","debounce","observe","disconnect","dispose","div","className","content","relationship","span","accessibilityData","ref","data-is-focusable"],"mappings":"AAAA;AAEA,wCAAwC,GACxC,YAAYA,WAAW,QAAQ;AAC/B,SAASC,WAAW,EAAEC,QAAQ,EAAEC,SAAS,EAAEC,MAAM,QAAQ,QAAQ;AACjE,SAASC,OAAO,QAAQ,0BAA0B;AAElD,SAASC,WAAW,QAAQ,mBAAmB;AAC/C,SAASC,uBAAuB,QAAQ,UAAU;AAElD,SAASC,KAAK,QAAQ,gBAAgB;AAatC,OAAO,MAAMC,qCAA4ET,MAAMU,UAAU,CAGvG,CAACC,OAAOC;IACR,MAAM,CAACC,cAAcC,gBAAgB,GAAGZ,SAAS;IACjD,MAAMa,eAAeX,OAAwB;IAC7C,MAAMY,QAAQZ,OAAO,IAAII,SAASS,OAAO;IACzC,MAAMC,iBAAiBd;IAEvB,MAAMe,mBAAmBlB,YAAY;QACnC,IAAI,CAACc,aAAaE,OAAO,IAAI,CAACF,aAAaE,OAAO,CAACG,aAAa,EAAE;YAChE,OAAOC;QACT;QACA,OAAON,aAAaE,OAAO,CAACG,aAAa;IAC3C,GAAG;QAACL;KAAa;IAEjB,MAAMO,oBAAoBrB,YAAY;QACpC,MAAMsB,kBAAkBJ;QACxB,MAAMK,iBAAiB,CAAC,CAACD,mBAAmBjB,YAAYiB;QACxD,IAAIC,mBAAmBX,cAAc;YACnCC,gBAAgBU;QAClB;IACF,GAAG;QAACL;QAAkBN;QAAcC;KAAgB;IAEpDX,UAAU;QACRmB;IACF,GAAG;QAACA;KAAkB;IAEtBnB,UAAU;QACR,6DAA6D;QAC7D,MAAMoB,kBAAkBJ;QACxB,IAAIM,OAAOC,cAAc,IAAIH,iBAAiB;YAC5CL,eAAeD,OAAO,GAAG,IAAIQ,OAAOC,cAAc,CAACV,MAAMW,QAAQ,CAACL,mBAAmB;YACrFJ,eAAeD,OAAO,CAACW,OAAO,CAACL;QACjC;QACA,yDAAyD;QACzD,OAAO;gBACLL;aAAAA,0BAAAA,eAAeD,OAAO,cAAtBC,8CAAAA,wBAAwBW,UAAU;YAClCb,MAAMc,OAAO;QACf;IACF,GAAG;QAACd;QAAOM;QAAmBH;KAAiB;IAE/C,qBACE,oBAACY;QAAIC,WAAWrB,MAAMqB,SAAS;qBAC7B,oBAAC3B;QAAQ4B,SAAStB,MAAMsB,OAAO;QAAEC,cAAa;qBAC5C,oBAACC;QAAM,GAAG5B,wBAAwBI,MAAMyB,iBAAiB,CAAC;QAAEC,KAAKtB;QAAcuB,qBAAmBzB;OAC/FF,MAAMsB,OAAO;AAKxB,GAAG"}
1
+ {"version":3,"sources":["../src/utilities/FocusableTooltipText.tsx"],"sourcesContent":["'use client';\n\n/* eslint-disable no-restricted-globals */\nimport * as React from 'react';\nimport { useCallback, useState, useEffect, useRef } from 'react';\nimport { Tooltip } from '@fluentui/react-tooltip';\nimport type { JSXElement } from '@fluentui/react-utilities';\nimport { hasOverflow } from './overflow-utils';\nimport { getAccessibleDataObject } from './index';\nimport { AccessibilityProps } from '../types/index';\nimport { Async } from './async-utils';\n\ninterface IFocusableTooltipTextProps {\n className?: string;\n content:\n | string\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n | JSXElement\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n | JSXElement[];\n accessibilityData?: AccessibilityProps;\n}\n\nexport const FocusableTooltipText: React.FunctionComponent<IFocusableTooltipTextProps> = React.forwardRef<\n HTMLDivElement,\n IFocusableTooltipTextProps\n>((props, forwardedRef) => {\n const [textOverflow, setTextOverflow] = useState(false);\n const tooltipChild = useRef<HTMLSpanElement>(null);\n const async = useRef(new Async()).current;\n const resizeObserver = useRef<ResizeObserver | undefined>(undefined);\n\n const getTargetElement = useCallback((): HTMLElement | undefined => {\n if (!tooltipChild.current || !tooltipChild.current.parentElement) {\n return undefined;\n }\n return tooltipChild.current.parentElement;\n }, [tooltipChild]);\n\n const checkTextOverflow = useCallback(() => {\n const overflowElement = getTargetElement();\n const isTextOverflow = !!overflowElement && hasOverflow(overflowElement);\n if (isTextOverflow !== textOverflow) {\n setTextOverflow(isTextOverflow);\n }\n }, [getTargetElement, textOverflow, setTextOverflow]);\n\n useEffect(() => {\n checkTextOverflow();\n }, [checkTextOverflow]);\n\n useEffect(() => {\n // setup part executed only when the component mounts/updates\n const overflowElement = getTargetElement();\n if (window.ResizeObserver && overflowElement) {\n resizeObserver.current = new window.ResizeObserver(async.debounce(checkTextOverflow, 500));\n resizeObserver.current.observe(overflowElement);\n }\n // cleanup part executed only when the component unmounts\n return () => {\n resizeObserver.current?.disconnect();\n async.dispose();\n };\n }, [async, checkTextOverflow, getTargetElement]);\n\n return (\n <div className={props.className}>\n <Tooltip content={props.content} relationship=\"description\">\n <span {...getAccessibleDataObject(props.accessibilityData)} ref={tooltipChild} data-is-focusable={textOverflow}>\n {props.content}\n </span>\n </Tooltip>\n </div>\n );\n});\n"],"names":["React","useCallback","useState","useEffect","useRef","Tooltip","hasOverflow","getAccessibleDataObject","Async","FocusableTooltipText","forwardRef","props","forwardedRef","textOverflow","setTextOverflow","tooltipChild","async","current","resizeObserver","undefined","getTargetElement","parentElement","checkTextOverflow","overflowElement","isTextOverflow","window","ResizeObserver","debounce","observe","disconnect","dispose","div","className","content","relationship","span","accessibilityData","ref","data-is-focusable"],"mappings":"AAAA;AAEA,wCAAwC,GACxC,YAAYA,WAAW,QAAQ;AAC/B,SAASC,WAAW,EAAEC,QAAQ,EAAEC,SAAS,EAAEC,MAAM,QAAQ,QAAQ;AACjE,SAASC,OAAO,QAAQ,0BAA0B;AAElD,SAASC,WAAW,QAAQ,mBAAmB;AAC/C,SAASC,uBAAuB,QAAQ,UAAU;AAElD,SAASC,KAAK,QAAQ,gBAAgB;AAatC,OAAO,MAAMC,qCAA4ET,MAAMU,UAAU,CAGvG,CAACC,OAAOC;IACR,MAAM,CAACC,cAAcC,gBAAgB,GAAGZ,SAAS;IACjD,MAAMa,eAAeX,OAAwB;IAC7C,MAAMY,QAAQZ,OAAO,IAAII,SAASS,OAAO;IACzC,MAAMC,iBAAiBd,OAAmCe;IAE1D,MAAMC,mBAAmBnB,YAAY;QACnC,IAAI,CAACc,aAAaE,OAAO,IAAI,CAACF,aAAaE,OAAO,CAACI,aAAa,EAAE;YAChE,OAAOF;QACT;QACA,OAAOJ,aAAaE,OAAO,CAACI,aAAa;IAC3C,GAAG;QAACN;KAAa;IAEjB,MAAMO,oBAAoBrB,YAAY;QACpC,MAAMsB,kBAAkBH;QACxB,MAAMI,iBAAiB,CAAC,CAACD,mBAAmBjB,YAAYiB;QACxD,IAAIC,mBAAmBX,cAAc;YACnCC,gBAAgBU;QAClB;IACF,GAAG;QAACJ;QAAkBP;QAAcC;KAAgB;IAEpDX,UAAU;QACRmB;IACF,GAAG;QAACA;KAAkB;IAEtBnB,UAAU;QACR,6DAA6D;QAC7D,MAAMoB,kBAAkBH;QACxB,IAAIK,OAAOC,cAAc,IAAIH,iBAAiB;YAC5CL,eAAeD,OAAO,GAAG,IAAIQ,OAAOC,cAAc,CAACV,MAAMW,QAAQ,CAACL,mBAAmB;YACrFJ,eAAeD,OAAO,CAACW,OAAO,CAACL;QACjC;QACA,yDAAyD;QACzD,OAAO;gBACLL;aAAAA,0BAAAA,eAAeD,OAAO,cAAtBC,8CAAAA,wBAAwBW,UAAU;YAClCb,MAAMc,OAAO;QACf;IACF,GAAG;QAACd;QAAOM;QAAmBF;KAAiB;IAE/C,qBACE,oBAACW;QAAIC,WAAWrB,MAAMqB,SAAS;qBAC7B,oBAAC3B;QAAQ4B,SAAStB,MAAMsB,OAAO;QAAEC,cAAa;qBAC5C,oBAACC;QAAM,GAAG5B,wBAAwBI,MAAMyB,iBAAiB,CAAC;QAAEC,KAAKtB;QAAcuB,qBAAmBzB;OAC/FF,MAAMsB,OAAO;AAKxB,GAAG"}
@@ -6,16 +6,21 @@ import { Tooltip } from '@fluentui/react-tooltip';
6
6
  import { Async } from './async-utils';
7
7
  import { KeyCodes } from './KeyCodes';
8
8
  import { useId } from '@fluentui/react-utilities';
9
- export const SVGTooltipText = /*#__PURE__*/ React.forwardRef((props, forwardedRef)=>{
9
+ export const SVGTooltipText = /*#__PURE__*/ React.forwardRef(({ delay = 0, showBackground = false, ...restProps }, forwardedRef)=>{
10
10
  var _props_textProps, _props_textProps1, _props_textProps2;
11
+ const props = {
12
+ delay,
13
+ showBackground,
14
+ ...restProps
15
+ };
11
16
  const [isTooltipVisible, setIsTooltipVisible] = useState(false);
12
17
  const [isOverflowing, setIsOverflowing] = useState(false);
13
18
  const [textWidth, setTextWidth] = useState(0);
14
19
  const [textHeight, setTextHeight] = useState(0);
15
20
  const tooltipHostRef = useRef(null);
16
21
  const async = useRef(new Async()).current;
17
- const dismissTimerId = useRef();
18
- const openTimerId = useRef();
22
+ const dismissTimerId = useRef(undefined);
23
+ const openTimerId = useRef(undefined);
19
24
  const tooltipHostId = useRef(useId('tooltip-host')).current;
20
25
  const ignoreNextFocusEvent = useRef(false);
21
26
  const portalMountNode = usePortalMountNode();
@@ -172,8 +177,3 @@ export const SVGTooltipText = /*#__PURE__*/ React.forwardRef((props, forwardedRe
172
177
  "data-is-focusable": props.shouldReceiveFocus && isOverflowing
173
178
  }, props.content)));
174
179
  });
175
- // eslint-disable-next-line @typescript-eslint/no-deprecated
176
- SVGTooltipText.defaultProps = {
177
- delay: 0,
178
- showBackground: false
179
- };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utilities/SVGTooltipText.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useState, useRef, useEffect, useCallback } from 'react';\nimport { usePortalMountNode } from '@fluentui/react-shared-contexts';\nimport { Tooltip } from '@fluentui/react-tooltip';\nimport { Async } from './async-utils';\nimport { KeyCodes } from './KeyCodes';\nimport { useId } from '@fluentui/react-utilities';\n\nexport interface SVGTooltipTextProps {\n closeDelay?: number;\n content: string;\n delay?: number;\n tooltipProps?: React.ComponentProps<typeof Tooltip>;\n textProps?: React.SVGAttributes<SVGTextElement>;\n maxWidth?: number;\n maxHeight?: number;\n shouldReceiveFocus?: boolean;\n isTooltipVisibleProp?: boolean;\n wrapContent?: (content: string, id: string, maxWidth: number, maxHeight?: number) => boolean;\n showBackground?: boolean;\n className?: string;\n}\n\nexport const SVGTooltipText: React.FunctionComponent<SVGTooltipTextProps> = React.forwardRef<\n HTMLDivElement,\n SVGTooltipTextProps\n>((props, forwardedRef) => {\n const [isTooltipVisible, setIsTooltipVisible] = useState(false);\n const [isOverflowing, setIsOverflowing] = useState(false);\n const [textWidth, setTextWidth] = useState(0);\n const [textHeight, setTextHeight] = useState(0);\n\n const tooltipHostRef = useRef<SVGTextElement>(null);\n const async = useRef(new Async()).current;\n const dismissTimerId = useRef<number>();\n const openTimerId = useRef<number>();\n const tooltipHostId = useRef(useId('tooltip-host')).current;\n const ignoreNextFocusEvent = useRef(false);\n const portalMountNode = usePortalMountNode();\n const PADDING = 3;\n\n const wrapContentCallback = useCallback(() => {\n if (\n props.content &&\n props.wrapContent &&\n props.wrapContent(props.content, tooltipHostId, props.maxWidth ?? 100, props.maxHeight)\n // ToDo - Specify a correct fallback value here\n ) {\n setIsOverflowing(true);\n } else {\n setIsOverflowing(false);\n }\n }, [props, tooltipHostId]);\n\n const measureText = useCallback((): void => {\n if (tooltipHostRef.current && typeof tooltipHostRef.current.getBBox === 'function') {\n const bbox = tooltipHostRef.current.getBBox();\n setTextWidth(bbox.width);\n setTextHeight(bbox.height);\n }\n }, []);\n\n useEffect(() => {\n wrapContentCallback();\n return () => {\n async.dispose();\n };\n }, [wrapContentCallback, async]);\n\n useEffect(() => {\n wrapContentCallback();\n }, [props.maxWidth, props.maxHeight, wrapContentCallback]);\n\n useEffect(() => {\n if (isTooltipVisible) {\n measureText();\n }\n }, [isTooltipVisible, measureText]);\n\n useEffect(() => {\n // Recalculate text dimensions when content or dimensions change\n measureText();\n }, [props.content, props.textProps, props.maxWidth, props.maxHeight, measureText]);\n\n const hideTooltip = useCallback(() => {\n async.clearTimeout(openTimerId.current!);\n async.clearTimeout(dismissTimerId.current!);\n setIsTooltipVisible(false);\n }, [async]);\n\n const onTooltipMouseEnter = useCallback(\n (ev: React.MouseEvent<SVGElement>) => {\n if (!isOverflowing) {\n return;\n }\n\n if (ev.target && portalMountNode?.contains(ev.target as HTMLElement)) {\n return;\n }\n\n async.clearTimeout(dismissTimerId.current!);\n async.clearTimeout(openTimerId.current!);\n\n if (props.delay !== 0) {\n openTimerId.current = async.setTimeout(() => {\n setIsTooltipVisible(true);\n }, props.delay!);\n } else {\n setIsTooltipVisible(true);\n }\n },\n [isOverflowing, portalMountNode, async, props.delay],\n );\n\n const onTooltipMouseLeave = useCallback(\n (ev: React.MouseEvent<SVGElement>) => {\n async.clearTimeout(dismissTimerId.current!);\n async.clearTimeout(openTimerId.current!);\n\n if (props.closeDelay) {\n dismissTimerId.current = async.setTimeout(() => {\n setIsTooltipVisible(false);\n }, props.closeDelay);\n } else {\n setIsTooltipVisible(false);\n }\n },\n [async, props.closeDelay],\n );\n\n const onTooltipFocus = useCallback(\n (ev: React.FocusEvent<SVGElement>) => {\n if (ignoreNextFocusEvent.current) {\n ignoreNextFocusEvent.current = false;\n return;\n }\n onTooltipMouseEnter(ev as unknown as React.MouseEvent<SVGElement>);\n },\n [onTooltipMouseEnter],\n );\n\n const onTooltipBlur = useCallback(\n (ev: React.FocusEvent<SVGElement>) => {\n ignoreNextFocusEvent.current = document?.activeElement === ev.target;\n dismissTimerId.current = async.setTimeout(() => {\n setIsTooltipVisible(false);\n }, 0);\n },\n [async],\n );\n\n const onTooltipKeyDown = useCallback(\n (ev: React.KeyboardEvent<SVGElement>) => {\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n if ((ev.which === KeyCodes.escape || ev.ctrlKey) && isTooltipVisible) {\n hideTooltip();\n ev.stopPropagation();\n }\n },\n [isTooltipVisible, hideTooltip],\n );\n\n const showTooltip =\n (props.isTooltipVisibleProp && isOverflowing && !!props.content) || (isTooltipVisible && !!props.content);\n\n const rectX = (typeof props.textProps?.x === 'number' ? props.textProps.x : 0) - (textWidth ?? 0) / 2 - PADDING;\n const rectY = (typeof props.textProps?.y === 'number' ? props.textProps.y : 0) - (textHeight ?? 0) / 2 - 2 * PADDING;\n\n return (\n <>\n {props.showBackground && (\n <rect\n x={rectX}\n y={rectY}\n width={(textWidth ?? 0) + 2 * PADDING}\n height={(textHeight ?? 0) + PADDING}\n transform={props.textProps?.transform}\n className={props.className}\n />\n )}\n <Tooltip\n relationship=\"description\"\n {...props.tooltipProps}\n withArrow\n content={props.content}\n // targetElement={getTargetElement()} ToDo - This assignment is causing build failure. Needs to be fixed.\n visible={showTooltip}\n >\n <text\n {...props.textProps}\n id={tooltipHostId}\n ref={tooltipHostRef}\n onFocusCapture={onTooltipFocus}\n onBlurCapture={onTooltipBlur}\n onMouseEnter={onTooltipMouseEnter}\n onMouseLeave={onTooltipMouseLeave}\n onKeyDown={onTooltipKeyDown}\n data-is-focusable={props.shouldReceiveFocus && isOverflowing}\n >\n {props.content}\n </text>\n </Tooltip>\n </>\n );\n});\n// eslint-disable-next-line @typescript-eslint/no-deprecated\nSVGTooltipText.defaultProps = {\n delay: 0,\n showBackground: false,\n};\n"],"names":["React","useState","useRef","useEffect","useCallback","usePortalMountNode","Tooltip","Async","KeyCodes","useId","SVGTooltipText","forwardRef","props","forwardedRef","isTooltipVisible","setIsTooltipVisible","isOverflowing","setIsOverflowing","textWidth","setTextWidth","textHeight","setTextHeight","tooltipHostRef","async","current","dismissTimerId","openTimerId","tooltipHostId","ignoreNextFocusEvent","portalMountNode","PADDING","wrapContentCallback","content","wrapContent","maxWidth","maxHeight","measureText","getBBox","bbox","width","height","dispose","textProps","hideTooltip","clearTimeout","onTooltipMouseEnter","ev","target","contains","delay","setTimeout","onTooltipMouseLeave","closeDelay","onTooltipFocus","onTooltipBlur","document","activeElement","onTooltipKeyDown","which","escape","ctrlKey","stopPropagation","showTooltip","isTooltipVisibleProp","rectX","x","rectY","y","showBackground","rect","transform","className","relationship","tooltipProps","withArrow","visible","text","id","ref","onFocusCapture","onBlurCapture","onMouseEnter","onMouseLeave","onKeyDown","data-is-focusable","shouldReceiveFocus","defaultProps"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/utilities/SVGTooltipText.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useState, useRef, useEffect, useCallback } from 'react';\nimport { usePortalMountNode } from '@fluentui/react-shared-contexts';\nimport { Tooltip } from '@fluentui/react-tooltip';\nimport { Async } from './async-utils';\nimport { KeyCodes } from './KeyCodes';\nimport { useId } from '@fluentui/react-utilities';\n\nexport interface SVGTooltipTextProps {\n closeDelay?: number;\n content: string;\n delay?: number;\n tooltipProps?: React.ComponentProps<typeof Tooltip>;\n textProps?: React.SVGAttributes<SVGTextElement>;\n maxWidth?: number;\n maxHeight?: number;\n shouldReceiveFocus?: boolean;\n isTooltipVisibleProp?: boolean;\n wrapContent?: (content: string, id: string, maxWidth: number, maxHeight?: number) => boolean;\n showBackground?: boolean;\n className?: string;\n}\n\nexport const SVGTooltipText: React.FunctionComponent<SVGTooltipTextProps> = React.forwardRef<\n HTMLDivElement,\n SVGTooltipTextProps\n>(({ delay = 0, showBackground = false, ...restProps }, forwardedRef) => {\n const props = { delay, showBackground, ...restProps };\n const [isTooltipVisible, setIsTooltipVisible] = useState(false);\n const [isOverflowing, setIsOverflowing] = useState(false);\n const [textWidth, setTextWidth] = useState(0);\n const [textHeight, setTextHeight] = useState(0);\n\n const tooltipHostRef = useRef<SVGTextElement>(null);\n const async = useRef(new Async()).current;\n const dismissTimerId = useRef<number | undefined>(undefined);\n const openTimerId = useRef<number | undefined>(undefined);\n const tooltipHostId = useRef(useId('tooltip-host')).current;\n const ignoreNextFocusEvent = useRef<boolean>(false);\n const portalMountNode = usePortalMountNode();\n const PADDING = 3;\n\n const wrapContentCallback = useCallback(() => {\n if (\n props.content &&\n props.wrapContent &&\n props.wrapContent(props.content, tooltipHostId, props.maxWidth ?? 100, props.maxHeight)\n // ToDo - Specify a correct fallback value here\n ) {\n setIsOverflowing(true);\n } else {\n setIsOverflowing(false);\n }\n }, [props, tooltipHostId]);\n\n const measureText = useCallback((): void => {\n if (tooltipHostRef.current && typeof tooltipHostRef.current.getBBox === 'function') {\n const bbox = tooltipHostRef.current.getBBox();\n setTextWidth(bbox.width);\n setTextHeight(bbox.height);\n }\n }, []);\n\n useEffect(() => {\n wrapContentCallback();\n return () => {\n async.dispose();\n };\n }, [wrapContentCallback, async]);\n\n useEffect(() => {\n wrapContentCallback();\n }, [props.maxWidth, props.maxHeight, wrapContentCallback]);\n\n useEffect(() => {\n if (isTooltipVisible) {\n measureText();\n }\n }, [isTooltipVisible, measureText]);\n\n useEffect(() => {\n // Recalculate text dimensions when content or dimensions change\n measureText();\n }, [props.content, props.textProps, props.maxWidth, props.maxHeight, measureText]);\n\n const hideTooltip = useCallback(() => {\n async.clearTimeout(openTimerId.current!);\n async.clearTimeout(dismissTimerId.current!);\n setIsTooltipVisible(false);\n }, [async]);\n\n const onTooltipMouseEnter = useCallback(\n (ev: React.MouseEvent<SVGElement>) => {\n if (!isOverflowing) {\n return;\n }\n\n if (ev.target && portalMountNode?.contains(ev.target as HTMLElement)) {\n return;\n }\n\n async.clearTimeout(dismissTimerId.current!);\n async.clearTimeout(openTimerId.current!);\n\n if (props.delay !== 0) {\n openTimerId.current = async.setTimeout(() => {\n setIsTooltipVisible(true);\n }, props.delay!);\n } else {\n setIsTooltipVisible(true);\n }\n },\n [isOverflowing, portalMountNode, async, props.delay],\n );\n\n const onTooltipMouseLeave = useCallback(\n (ev: React.MouseEvent<SVGElement>) => {\n async.clearTimeout(dismissTimerId.current!);\n async.clearTimeout(openTimerId.current!);\n\n if (props.closeDelay) {\n dismissTimerId.current = async.setTimeout(() => {\n setIsTooltipVisible(false);\n }, props.closeDelay);\n } else {\n setIsTooltipVisible(false);\n }\n },\n [async, props.closeDelay],\n );\n\n const onTooltipFocus = useCallback(\n (ev: React.FocusEvent<SVGElement>) => {\n if (ignoreNextFocusEvent.current) {\n ignoreNextFocusEvent.current = false;\n return;\n }\n onTooltipMouseEnter(ev as unknown as React.MouseEvent<SVGElement>);\n },\n [onTooltipMouseEnter],\n );\n\n const onTooltipBlur = useCallback(\n (ev: React.FocusEvent<SVGElement>) => {\n ignoreNextFocusEvent.current = document?.activeElement === ev.target;\n dismissTimerId.current = async.setTimeout(() => {\n setIsTooltipVisible(false);\n }, 0);\n },\n [async],\n );\n\n const onTooltipKeyDown = useCallback(\n (ev: React.KeyboardEvent<SVGElement>) => {\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n if ((ev.which === KeyCodes.escape || ev.ctrlKey) && isTooltipVisible) {\n hideTooltip();\n ev.stopPropagation();\n }\n },\n [isTooltipVisible, hideTooltip],\n );\n\n const showTooltip =\n (props.isTooltipVisibleProp && isOverflowing && !!props.content) || (isTooltipVisible && !!props.content);\n\n const rectX = (typeof props.textProps?.x === 'number' ? props.textProps.x : 0) - (textWidth ?? 0) / 2 - PADDING;\n const rectY = (typeof props.textProps?.y === 'number' ? props.textProps.y : 0) - (textHeight ?? 0) / 2 - 2 * PADDING;\n\n return (\n <>\n {props.showBackground && (\n <rect\n x={rectX}\n y={rectY}\n width={(textWidth ?? 0) + 2 * PADDING}\n height={(textHeight ?? 0) + PADDING}\n transform={props.textProps?.transform}\n className={props.className}\n />\n )}\n <Tooltip\n relationship=\"description\"\n {...props.tooltipProps}\n withArrow\n content={props.content}\n // targetElement={getTargetElement()} ToDo - This assignment is causing build failure. Needs to be fixed.\n visible={showTooltip}\n >\n <text\n {...props.textProps}\n id={tooltipHostId}\n ref={tooltipHostRef}\n onFocusCapture={onTooltipFocus}\n onBlurCapture={onTooltipBlur}\n onMouseEnter={onTooltipMouseEnter}\n onMouseLeave={onTooltipMouseLeave}\n onKeyDown={onTooltipKeyDown}\n data-is-focusable={props.shouldReceiveFocus && isOverflowing}\n >\n {props.content}\n </text>\n </Tooltip>\n </>\n );\n});\n"],"names":["React","useState","useRef","useEffect","useCallback","usePortalMountNode","Tooltip","Async","KeyCodes","useId","SVGTooltipText","forwardRef","delay","showBackground","restProps","forwardedRef","props","isTooltipVisible","setIsTooltipVisible","isOverflowing","setIsOverflowing","textWidth","setTextWidth","textHeight","setTextHeight","tooltipHostRef","async","current","dismissTimerId","undefined","openTimerId","tooltipHostId","ignoreNextFocusEvent","portalMountNode","PADDING","wrapContentCallback","content","wrapContent","maxWidth","maxHeight","measureText","getBBox","bbox","width","height","dispose","textProps","hideTooltip","clearTimeout","onTooltipMouseEnter","ev","target","contains","setTimeout","onTooltipMouseLeave","closeDelay","onTooltipFocus","onTooltipBlur","document","activeElement","onTooltipKeyDown","which","escape","ctrlKey","stopPropagation","showTooltip","isTooltipVisibleProp","rectX","x","rectY","y","rect","transform","className","relationship","tooltipProps","withArrow","visible","text","id","ref","onFocusCapture","onBlurCapture","onMouseEnter","onMouseLeave","onKeyDown","data-is-focusable","shouldReceiveFocus"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  'use client';
2
2
  import { create as d3Create, select as d3Select } from 'd3-selection';
3
+ import { isHTMLElement } from '@fluentui/react-utilities';
3
4
  import { copyStyle, createMeasurementSpan, resolveCSSVariables } from './index';
4
5
  import { LEGEND_CONTAINER_MARGIN_TOP, LEGEND_CONTAINER_MARGIN_START, LEGEND_PADDING, LEGEND_HEIGHT, LEGEND_SHAPE_BORDER, LEGEND_SHAPE_SIZE, LEGEND_SHAPE_MARGIN_END, INACTIVE_LEGEND_TEXT_OPACITY } from '../components/Legends/useLegendsStyles.styles';
5
6
  export function toImage(chartContainer, legendsToSvgCallback, isRTL = false, opts = {}) {
@@ -53,6 +54,55 @@ const SVG_TEXT_STYLE_PROPERTIES = [
53
54
  'text-align',
54
55
  'border'
55
56
  ];
57
+ const ANNOTATION_HTML_STYLE_PROPERTIES = [
58
+ 'align-items',
59
+ 'background',
60
+ 'background-color',
61
+ 'border',
62
+ 'border-radius',
63
+ 'box-shadow',
64
+ 'box-sizing',
65
+ 'color',
66
+ 'column-gap',
67
+ 'display',
68
+ 'flex',
69
+ 'flex-direction',
70
+ 'font-family',
71
+ 'font-size',
72
+ 'font-style',
73
+ 'font-weight',
74
+ 'gap',
75
+ 'height',
76
+ 'justify-content',
77
+ 'letter-spacing',
78
+ 'line-height',
79
+ 'margin',
80
+ 'max-height',
81
+ 'max-width',
82
+ 'min-height',
83
+ 'min-width',
84
+ 'opacity',
85
+ 'overflow',
86
+ 'padding',
87
+ 'pointer-events',
88
+ 'position',
89
+ 'row-gap',
90
+ 'text-align',
91
+ 'text-decoration',
92
+ 'text-transform',
93
+ 'top',
94
+ 'right',
95
+ 'bottom',
96
+ 'left',
97
+ 'visibility',
98
+ 'white-space',
99
+ 'width',
100
+ 'z-index'
101
+ ];
102
+ const ANNOTATION_FOREIGN_OBJECT_STYLE_PROPERTIES = [
103
+ 'overflow',
104
+ 'pointer-events'
105
+ ];
56
106
  function toSVG(chartContainer, legendsToSvgCallback, isRTL, background) {
57
107
  const svg = chartContainer.querySelector('svg');
58
108
  if (!svg) {
@@ -87,6 +137,27 @@ function toSVG(chartContainer, legendsToSvgCallback, isRTL, background) {
87
137
  svgElements = null;
88
138
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
89
139
  clonedSvgElements = null;
140
+ const originalForeignObjects = svg.querySelectorAll('foreignObject');
141
+ const clonedForeignObjects = clonedSvg.node().querySelectorAll('foreignObject');
142
+ originalForeignObjects.forEach((originalFo, index)=>{
143
+ const clonedFo = clonedForeignObjects[index];
144
+ if (!clonedFo) {
145
+ return;
146
+ }
147
+ const originalRoot = originalFo.firstElementChild;
148
+ const clonedRoot = clonedFo.firstElementChild;
149
+ if (originalRoot && clonedRoot) {
150
+ copyStyle(ANNOTATION_HTML_STYLE_PROPERTIES, originalRoot, clonedRoot);
151
+ }
152
+ const originalHtmlElements = originalFo.querySelectorAll('*');
153
+ const clonedHtmlElements = clonedFo.querySelectorAll('*');
154
+ originalHtmlElements.forEach((originalEl, elementIndex)=>{
155
+ const clonedEl = clonedHtmlElements[elementIndex];
156
+ if (clonedEl) {
157
+ copyStyle(ANNOTATION_HTML_STYLE_PROPERTIES, originalEl, clonedEl);
158
+ }
159
+ });
160
+ });
90
161
  const { width: svgWidth, height: svgHeight } = svg.getBoundingClientRect();
91
162
  const legendGroup = typeof legendsToSvgCallback === 'function' ? legendsToSvgCallback(svgWidth, isRTL) : {
92
163
  node: null,
@@ -95,12 +166,49 @@ function toSVG(chartContainer, legendsToSvgCallback, isRTL, background) {
95
166
  };
96
167
  const w1 = Math.max(svgWidth, legendGroup.width);
97
168
  const h1 = svgHeight + legendGroup.height;
169
+ const annotationSvg = chartContainer.querySelector('[data-chart-annotation-svg="true"]');
170
+ let annotationClone = null;
171
+ if (annotationSvg) {
172
+ annotationClone = annotationSvg.cloneNode(true);
173
+ copyStyle(SVG_STYLE_PROPERTIES, annotationSvg, annotationClone);
174
+ const annotationElements = annotationSvg.getElementsByTagName('*');
175
+ const clonedAnnotationElements = annotationClone.getElementsByTagName('*');
176
+ for(let i = 0; i < annotationElements.length; i++){
177
+ const original = annotationElements[i];
178
+ const cloned = clonedAnnotationElements[i];
179
+ const tag = original.tagName.toLowerCase();
180
+ const isSvgElement = original instanceof SVGElement;
181
+ const isTextElement = tag === 'text';
182
+ const isHtmlElement = isHTMLElement(original);
183
+ if (isSvgElement) {
184
+ if (isTextElement) {
185
+ copyStyle([
186
+ ...SVG_STYLE_PROPERTIES,
187
+ ...SVG_TEXT_STYLE_PROPERTIES
188
+ ], original, cloned);
189
+ } else {
190
+ copyStyle(SVG_STYLE_PROPERTIES, original, cloned);
191
+ }
192
+ }
193
+ if (isHtmlElement) {
194
+ copyStyle(ANNOTATION_HTML_STYLE_PROPERTIES, original, cloned);
195
+ }
196
+ if (tag === 'foreignobject') {
197
+ copyStyle(ANNOTATION_FOREIGN_OBJECT_STYLE_PROPERTIES, original, cloned);
198
+ }
199
+ }
200
+ }
98
201
  if (legendGroup.node) {
99
202
  d3Select(legendGroup.node).attr('transform', `translate(0, ${svgHeight})`);
100
203
  clonedSvg.append(()=>legendGroup.node);
101
204
  }
102
205
  clonedSvg.insert('rect', ':first-child').attr('x', 0).attr('y', 0).attr('width', w1).attr('height', h1).attr('fill', background);
103
206
  clonedSvg.attr('width', w1).attr('height', h1).attr('viewBox', `0 0 ${w1} ${h1}`).attr('direction', isRTL ? 'rtl' : 'ltr');
207
+ if (annotationClone) {
208
+ clonedSvg.selectAll('[data-chart-annotation-layer="true"]').remove();
209
+ d3Select(annotationClone).attr('x', 0).attr('y', 0).attr('width', svgWidth).attr('height', svgHeight);
210
+ clonedSvg.append(()=>annotationClone);
211
+ }
104
212
  const result = {
105
213
  node: clonedSvg.node(),
106
214
  width: w1,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utilities/image-export-utils.ts"],"sourcesContent":["'use client';\n\nimport { create as d3Create, select as d3Select, Selection } from 'd3-selection';\nimport { copyStyle, createMeasurementSpan, resolveCSSVariables } from './index';\nimport { ImageExportOptions } from '../types/index';\nimport { Legend, LegendContainer } from '../Legends';\nimport {\n LEGEND_CONTAINER_MARGIN_TOP,\n LEGEND_CONTAINER_MARGIN_START,\n LEGEND_PADDING,\n LEGEND_HEIGHT,\n LEGEND_SHAPE_BORDER,\n LEGEND_SHAPE_SIZE,\n LEGEND_SHAPE_MARGIN_END,\n INACTIVE_LEGEND_TEXT_OPACITY,\n} from '../components/Legends/useLegendsStyles.styles';\n\nexport function toImage(\n chartContainer: HTMLElement | null | undefined,\n legendsToSvgCallback?: LegendContainer['toSVG'],\n isRTL: boolean = false,\n opts: ImageExportOptions = {},\n): Promise<string> {\n return new Promise((resolve, reject) => {\n if (!chartContainer) {\n return reject(new Error('Chart container is not defined'));\n }\n\n try {\n const background =\n typeof opts.background === 'string' ? resolveCSSVariables(chartContainer, opts.background) : 'transparent';\n\n const svg = toSVG(chartContainer, legendsToSvgCallback, isRTL, background);\n if (!svg.node) {\n return reject(new Error('SVG node is null'));\n }\n\n let svgData = new XMLSerializer().serializeToString(svg.node);\n // This node is already detached from the DOM, so there's no need to call remove() on it.\n // Just clear the reference.\n svg.node = null;\n\n let svgDataUrl = 'data:image/svg+xml;base64,' + btoa(unescapePonyfill(encodeURIComponent(svgData)));\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n svgData = null as any;\n\n svgToPng(svgDataUrl, {\n width: opts.width || svg.width,\n height: opts.height || svg.height,\n scale: opts.scale,\n })\n .then(resolve)\n .catch(reject);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n svgDataUrl = null as any;\n } catch (err) {\n return reject(err);\n }\n });\n}\n\nconst SVG_STYLE_PROPERTIES = [\n 'display',\n 'fill',\n 'fill-opacity',\n 'opacity',\n 'stroke',\n 'stroke-width',\n 'transform',\n 'border-collapse',\n];\nconst SVG_TEXT_STYLE_PROPERTIES = [\n 'font-family',\n 'font-size',\n 'font-weight',\n 'text-anchor',\n 'background-color',\n 'color',\n 'padding',\n 'text-align',\n 'border',\n];\n\nfunction toSVG(\n chartContainer: HTMLElement,\n legendsToSvgCallback: LegendContainer['toSVG'] | undefined,\n isRTL: boolean,\n background: string,\n) {\n const svg = chartContainer.querySelector<SVGSVGElement>('svg');\n if (!svg) {\n throw new Error('SVG not found');\n }\n\n let clonedSvg = d3Select(svg.cloneNode(true) as SVGSVGElement)\n .attr('width', null)\n .attr('height', null)\n .attr('viewBox', null);\n let svgElements = svg.getElementsByTagName('*');\n let clonedSvgElements = clonedSvg.node()!.getElementsByTagName('*');\n\n const TEXT_ELEMENTS = ['text'];\n const TABLE_ELEMENTS = ['table', 'thead', 'tbody', 'tr', 'th', 'td'];\n\n for (let i = 0; i < svgElements.length; i++) {\n const tag = svgElements[i].tagName.toLowerCase();\n\n if (TEXT_ELEMENTS.includes(tag) || TABLE_ELEMENTS.includes(tag)) {\n copyStyle([...SVG_STYLE_PROPERTIES, ...SVG_TEXT_STYLE_PROPERTIES], svgElements[i], clonedSvgElements[i]);\n } else {\n copyStyle(SVG_STYLE_PROPERTIES, svgElements[i], clonedSvgElements[i]);\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n svgElements = null as any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n clonedSvgElements = null as any;\n\n const { width: svgWidth, height: svgHeight } = svg.getBoundingClientRect();\n const legendGroup =\n typeof legendsToSvgCallback === 'function'\n ? legendsToSvgCallback(svgWidth, isRTL)\n : { node: null, width: 0, height: 0 };\n const w1 = Math.max(svgWidth, legendGroup.width);\n const h1 = svgHeight + legendGroup.height;\n\n if (legendGroup.node) {\n d3Select(legendGroup.node).attr('transform', `translate(0, ${svgHeight})`);\n clonedSvg.append(() => legendGroup.node);\n }\n clonedSvg\n .insert('rect', ':first-child')\n .attr('x', 0)\n .attr('y', 0)\n .attr('width', w1)\n .attr('height', h1)\n .attr('fill', background);\n clonedSvg\n .attr('width', w1)\n .attr('height', h1)\n .attr('viewBox', `0 0 ${w1} ${h1}`)\n .attr('direction', isRTL ? 'rtl' : 'ltr');\n\n const result = {\n node: clonedSvg.node(),\n width: w1,\n height: h1,\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n clonedSvg = null as any;\n\n return result;\n}\n\nconst LEGEND_TEXT_STYLE_PROPERTIES_MAP = {\n color: 'fill',\n 'font-family': 'font-family',\n 'font-size': 'font-size',\n 'font-weight': 'font-weight',\n};\n\nexport function cloneLegendsToSVG(\n legends: Legend[],\n svgWidth: number,\n config: {\n selectedLegends: Record<string, boolean>;\n centerLegends: boolean;\n textClassName: string;\n isRTL: boolean;\n },\n legendContainer?: HTMLElement | null,\n): {\n node: SVGGElement | null;\n width: number;\n height: number;\n} {\n if (legends.length === 0) {\n return {\n node: null,\n width: 0,\n height: 0,\n };\n }\n\n const { selectedLegends, centerLegends, textClassName, isRTL } = config;\n const legendGroup = d3Create<SVGGElement>('svg:g');\n let legendX = centerLegends ? 0 : LEGEND_CONTAINER_MARGIN_START;\n let legendY = LEGEND_CONTAINER_MARGIN_TOP;\n let legendLine: { elem: Selection<SVGGElement, unknown, null, undefined>; width: number }[] = [];\n const legendLines: (typeof legendLine)[] = [];\n const legendLineWidths: number[] = [];\n const noLegendsSelected = Object.keys(selectedLegends).length === 0;\n\n for (let i = 0; i < legends.length; i++) {\n const textOffset = LEGEND_PADDING + LEGEND_SHAPE_SIZE + LEGEND_SHAPE_MARGIN_END;\n const legendText = createMeasurementSpan(legends[i].title, textClassName, legendContainer);\n const legendWidth = textOffset + legendText.getBoundingClientRect().width + LEGEND_PADDING;\n const legendItem = legendGroup.append('g');\n\n legendLine.push({ elem: legendItem, width: legendWidth });\n if (legendX + legendWidth > svgWidth && legendLine.length > 1) {\n legendLine.pop();\n legendLines.push(legendLine);\n legendLineWidths.push(legendX);\n\n legendLine = [{ elem: legendItem, width: legendWidth }];\n legendX = centerLegends ? 0 : LEGEND_CONTAINER_MARGIN_START;\n legendY += LEGEND_HEIGHT;\n }\n\n const isLegendActive = selectedLegends[legends[i].title] || noLegendsSelected;\n\n legendItem\n .append('rect')\n .attr('x', legendX + (isRTL ? legendWidth - LEGEND_PADDING - LEGEND_SHAPE_SIZE : LEGEND_PADDING))\n .attr('y', legendY + LEGEND_PADDING)\n .attr('width', LEGEND_SHAPE_SIZE)\n .attr('height', LEGEND_SHAPE_SIZE)\n .style('fill', isLegendActive ? legends[i].color : 'transparent')\n .style('stroke-width', LEGEND_SHAPE_BORDER)\n .style('stroke', legends[i].color);\n\n legendItem\n .append('text')\n .attr('x', legendX + (isRTL ? legendWidth - textOffset : textOffset))\n .attr('y', legendY + LEGEND_PADDING)\n .attr('dominant-baseline', 'hanging')\n .style('opacity', isLegendActive ? 1 : INACTIVE_LEGEND_TEXT_OPACITY)\n .text(legends[i].title)\n .call(selection => copyStyle(LEGEND_TEXT_STYLE_PROPERTIES_MAP, legendText, selection.node()!));\n\n legendX += legendWidth;\n }\n\n legendLines.push(legendLine);\n legendLineWidths.push(legendX);\n legendY += LEGEND_HEIGHT;\n\n if (centerLegends) {\n legendLines.forEach((ln, idx) => {\n const lineOffsetX = Math.max((svgWidth - legendLineWidths[idx]) / 2, 0);\n let remLineWidth = legendLineWidths[idx];\n let itemOffsetX = 0;\n ln.forEach(item => {\n const newOffsetX = lineOffsetX + (isRTL ? remLineWidth - item.width - itemOffsetX : 0);\n item.elem.attr('transform', `translate(${newOffsetX}, 0)`);\n remLineWidth -= item.width;\n itemOffsetX += item.width;\n });\n });\n } else if (isRTL) {\n const w1 = Math.max(svgWidth, ...legendLineWidths);\n legendLines.forEach(ln => {\n let remLineWidth = w1 - LEGEND_CONTAINER_MARGIN_START;\n let itemOffsetX = LEGEND_CONTAINER_MARGIN_START;\n ln.forEach(item => {\n const newOffsetX = remLineWidth - item.width - itemOffsetX;\n item.elem.attr('transform', `translate(${newOffsetX}, 0)`);\n remLineWidth -= item.width;\n itemOffsetX += item.width;\n });\n });\n }\n\n return {\n node: legendGroup.node(),\n width: Math.max(...legendLineWidths),\n height: legendY,\n };\n}\n\nfunction svgToPng(svgDataUrl: string, opts: ImageExportOptions = {}): Promise<string> {\n return new Promise((resolve, reject) => {\n const scale = opts.scale || 1;\n const w0 = opts.width || 300;\n const h0 = opts.height || 150;\n const w1 = scale * w0;\n const h1 = scale * h0;\n\n const canvas = document.createElement('canvas');\n const img = new Image();\n\n canvas.width = w1;\n canvas.height = h1;\n\n img.onload = function () {\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n return reject(new Error('Canvas context is null'));\n }\n\n ctx.clearRect(0, 0, w1, h1);\n ctx.drawImage(img, 0, 0, w1, h1);\n\n const imgData = canvas.toDataURL('image/png');\n resolve(imgData);\n };\n\n img.onerror = function (err) {\n reject(err);\n };\n\n img.src = svgDataUrl;\n });\n}\n\nconst hex2 = /^[\\da-f]{2}$/i;\nconst hex4 = /^[\\da-f]{4}$/i;\n\n/**\n * A ponyfill for the deprecated `unescape` method, taken from the `core-js` library.\n *\n * Source: {@link https://github.com/zloirock/core-js/blob/167136f479d3b8519953f2e4c534ecdd1031d3cf/packages/core-js/modules/es.unescape.js core-js/packages/core-js/modules/es.unescape.js}\n */\nfunction unescapePonyfill(str: string) {\n let result = '';\n const length = str.length;\n let index = 0;\n let chr;\n let part;\n while (index < length) {\n chr = str.charAt(index++);\n if (chr === '%') {\n if (str.charAt(index) === 'u') {\n part = str.slice(index + 1, index + 5);\n if (hex4.exec(part)) {\n result += String.fromCharCode(parseInt(part, 16));\n index += 5;\n continue;\n }\n } else {\n part = str.slice(index, index + 2);\n if (hex2.exec(part)) {\n result += String.fromCharCode(parseInt(part, 16));\n index += 2;\n continue;\n }\n }\n }\n result += chr;\n }\n return result;\n}\n"],"names":["create","d3Create","select","d3Select","copyStyle","createMeasurementSpan","resolveCSSVariables","LEGEND_CONTAINER_MARGIN_TOP","LEGEND_CONTAINER_MARGIN_START","LEGEND_PADDING","LEGEND_HEIGHT","LEGEND_SHAPE_BORDER","LEGEND_SHAPE_SIZE","LEGEND_SHAPE_MARGIN_END","INACTIVE_LEGEND_TEXT_OPACITY","toImage","chartContainer","legendsToSvgCallback","isRTL","opts","Promise","resolve","reject","Error","background","svg","toSVG","node","svgData","XMLSerializer","serializeToString","svgDataUrl","btoa","unescapePonyfill","encodeURIComponent","svgToPng","width","height","scale","then","catch","err","SVG_STYLE_PROPERTIES","SVG_TEXT_STYLE_PROPERTIES","querySelector","clonedSvg","cloneNode","attr","svgElements","getElementsByTagName","clonedSvgElements","TEXT_ELEMENTS","TABLE_ELEMENTS","i","length","tag","tagName","toLowerCase","includes","svgWidth","svgHeight","getBoundingClientRect","legendGroup","w1","Math","max","h1","append","insert","result","LEGEND_TEXT_STYLE_PROPERTIES_MAP","color","cloneLegendsToSVG","legends","config","legendContainer","selectedLegends","centerLegends","textClassName","legendX","legendY","legendLine","legendLines","legendLineWidths","noLegendsSelected","Object","keys","textOffset","legendText","title","legendWidth","legendItem","push","elem","pop","isLegendActive","style","text","call","selection","forEach","ln","idx","lineOffsetX","remLineWidth","itemOffsetX","item","newOffsetX","w0","h0","canvas","document","createElement","img","Image","onload","ctx","getContext","clearRect","drawImage","imgData","toDataURL","onerror","src","hex2","hex4","str","index","chr","part","charAt","slice","exec","String","fromCharCode","parseInt"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/utilities/image-export-utils.ts"],"sourcesContent":["'use client';\n\nimport { create as d3Create, select as d3Select, Selection } from 'd3-selection';\nimport { isHTMLElement } from '@fluentui/react-utilities';\nimport { copyStyle, createMeasurementSpan, resolveCSSVariables } from './index';\nimport { ImageExportOptions } from '../types/index';\nimport { Legend, LegendContainer } from '../Legends';\nimport {\n LEGEND_CONTAINER_MARGIN_TOP,\n LEGEND_CONTAINER_MARGIN_START,\n LEGEND_PADDING,\n LEGEND_HEIGHT,\n LEGEND_SHAPE_BORDER,\n LEGEND_SHAPE_SIZE,\n LEGEND_SHAPE_MARGIN_END,\n INACTIVE_LEGEND_TEXT_OPACITY,\n} from '../components/Legends/useLegendsStyles.styles';\n\nexport function toImage(\n chartContainer: HTMLElement | null | undefined,\n legendsToSvgCallback?: LegendContainer['toSVG'],\n isRTL: boolean = false,\n opts: ImageExportOptions = {},\n): Promise<string> {\n return new Promise((resolve, reject) => {\n if (!chartContainer) {\n return reject(new Error('Chart container is not defined'));\n }\n\n try {\n const background =\n typeof opts.background === 'string' ? resolveCSSVariables(chartContainer, opts.background) : 'transparent';\n\n const svg = toSVG(chartContainer, legendsToSvgCallback, isRTL, background);\n if (!svg.node) {\n return reject(new Error('SVG node is null'));\n }\n\n let svgData = new XMLSerializer().serializeToString(svg.node);\n // This node is already detached from the DOM, so there's no need to call remove() on it.\n // Just clear the reference.\n svg.node = null;\n\n let svgDataUrl = 'data:image/svg+xml;base64,' + btoa(unescapePonyfill(encodeURIComponent(svgData)));\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n svgData = null as any;\n\n svgToPng(svgDataUrl, {\n width: opts.width || svg.width,\n height: opts.height || svg.height,\n scale: opts.scale,\n })\n .then(resolve)\n .catch(reject);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n svgDataUrl = null as any;\n } catch (err) {\n return reject(err);\n }\n });\n}\n\nconst SVG_STYLE_PROPERTIES = [\n 'display',\n 'fill',\n 'fill-opacity',\n 'opacity',\n 'stroke',\n 'stroke-width',\n 'transform',\n 'border-collapse',\n];\nconst SVG_TEXT_STYLE_PROPERTIES = [\n 'font-family',\n 'font-size',\n 'font-weight',\n 'text-anchor',\n 'background-color',\n 'color',\n 'padding',\n 'text-align',\n 'border',\n];\n\nconst ANNOTATION_HTML_STYLE_PROPERTIES = [\n 'align-items',\n 'background',\n 'background-color',\n 'border',\n 'border-radius',\n 'box-shadow',\n 'box-sizing',\n 'color',\n 'column-gap',\n 'display',\n 'flex',\n 'flex-direction',\n 'font-family',\n 'font-size',\n 'font-style',\n 'font-weight',\n 'gap',\n 'height',\n 'justify-content',\n 'letter-spacing',\n 'line-height',\n 'margin',\n 'max-height',\n 'max-width',\n 'min-height',\n 'min-width',\n 'opacity',\n 'overflow',\n 'padding',\n 'pointer-events',\n 'position',\n 'row-gap',\n 'text-align',\n 'text-decoration',\n 'text-transform',\n 'top',\n 'right',\n 'bottom',\n 'left',\n 'visibility',\n 'white-space',\n 'width',\n 'z-index',\n];\nconst ANNOTATION_FOREIGN_OBJECT_STYLE_PROPERTIES = ['overflow', 'pointer-events'];\n\nfunction toSVG(\n chartContainer: HTMLElement,\n legendsToSvgCallback: LegendContainer['toSVG'] | undefined,\n isRTL: boolean,\n background: string,\n) {\n const svg = chartContainer.querySelector<SVGSVGElement>('svg');\n if (!svg) {\n throw new Error('SVG not found');\n }\n\n let clonedSvg = d3Select(svg.cloneNode(true) as SVGSVGElement)\n .attr('width', null)\n .attr('height', null)\n .attr('viewBox', null);\n let svgElements = svg.getElementsByTagName('*');\n let clonedSvgElements = clonedSvg.node()!.getElementsByTagName('*');\n\n const TEXT_ELEMENTS = ['text'];\n const TABLE_ELEMENTS = ['table', 'thead', 'tbody', 'tr', 'th', 'td'];\n\n for (let i = 0; i < svgElements.length; i++) {\n const tag = svgElements[i].tagName.toLowerCase();\n\n if (TEXT_ELEMENTS.includes(tag) || TABLE_ELEMENTS.includes(tag)) {\n copyStyle([...SVG_STYLE_PROPERTIES, ...SVG_TEXT_STYLE_PROPERTIES], svgElements[i], clonedSvgElements[i]);\n } else {\n copyStyle(SVG_STYLE_PROPERTIES, svgElements[i], clonedSvgElements[i]);\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n svgElements = null as any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n clonedSvgElements = null as any;\n\n const originalForeignObjects = svg.querySelectorAll('foreignObject');\n const clonedForeignObjects = clonedSvg.node()!.querySelectorAll('foreignObject');\n\n originalForeignObjects.forEach((originalFo, index) => {\n const clonedFo = clonedForeignObjects[index];\n if (!clonedFo) {\n return;\n }\n\n const originalRoot = originalFo.firstElementChild as HTMLElement | null;\n const clonedRoot = clonedFo.firstElementChild as HTMLElement | null;\n\n if (originalRoot && clonedRoot) {\n copyStyle(ANNOTATION_HTML_STYLE_PROPERTIES, originalRoot, clonedRoot);\n }\n\n const originalHtmlElements = originalFo.querySelectorAll<HTMLElement>('*');\n const clonedHtmlElements = clonedFo.querySelectorAll<HTMLElement>('*');\n\n originalHtmlElements.forEach((originalEl, elementIndex) => {\n const clonedEl = clonedHtmlElements[elementIndex];\n if (clonedEl) {\n copyStyle(ANNOTATION_HTML_STYLE_PROPERTIES, originalEl, clonedEl);\n }\n });\n });\n\n const { width: svgWidth, height: svgHeight } = svg.getBoundingClientRect();\n const legendGroup =\n typeof legendsToSvgCallback === 'function'\n ? legendsToSvgCallback(svgWidth, isRTL)\n : { node: null, width: 0, height: 0 };\n const w1 = Math.max(svgWidth, legendGroup.width);\n const h1 = svgHeight + legendGroup.height;\n\n const annotationSvg = chartContainer.querySelector<SVGSVGElement>('[data-chart-annotation-svg=\"true\"]');\n let annotationClone: SVGSVGElement | null = null;\n\n if (annotationSvg) {\n annotationClone = annotationSvg.cloneNode(true) as SVGSVGElement;\n copyStyle(SVG_STYLE_PROPERTIES, annotationSvg, annotationClone);\n\n const annotationElements = annotationSvg.getElementsByTagName('*');\n const clonedAnnotationElements = annotationClone.getElementsByTagName('*');\n\n for (let i = 0; i < annotationElements.length; i++) {\n const original = annotationElements[i];\n const cloned = clonedAnnotationElements[i];\n const tag = original.tagName.toLowerCase();\n const isSvgElement = original instanceof SVGElement;\n const isTextElement = tag === 'text';\n const isHtmlElement = isHTMLElement(original);\n\n if (isSvgElement) {\n if (isTextElement) {\n copyStyle([...SVG_STYLE_PROPERTIES, ...SVG_TEXT_STYLE_PROPERTIES], original, cloned);\n } else {\n copyStyle(SVG_STYLE_PROPERTIES, original, cloned);\n }\n }\n\n if (isHtmlElement) {\n copyStyle(ANNOTATION_HTML_STYLE_PROPERTIES, original, cloned);\n }\n\n if (tag === 'foreignobject') {\n copyStyle(ANNOTATION_FOREIGN_OBJECT_STYLE_PROPERTIES, original, cloned);\n }\n }\n }\n\n if (legendGroup.node) {\n d3Select(legendGroup.node).attr('transform', `translate(0, ${svgHeight})`);\n clonedSvg.append(() => legendGroup.node);\n }\n clonedSvg\n .insert('rect', ':first-child')\n .attr('x', 0)\n .attr('y', 0)\n .attr('width', w1)\n .attr('height', h1)\n .attr('fill', background);\n clonedSvg\n .attr('width', w1)\n .attr('height', h1)\n .attr('viewBox', `0 0 ${w1} ${h1}`)\n .attr('direction', isRTL ? 'rtl' : 'ltr');\n\n if (annotationClone) {\n clonedSvg.selectAll('[data-chart-annotation-layer=\"true\"]').remove();\n d3Select(annotationClone).attr('x', 0).attr('y', 0).attr('width', svgWidth).attr('height', svgHeight);\n clonedSvg.append(() => annotationClone as SVGSVGElement);\n }\n const result = {\n node: clonedSvg.node(),\n width: w1,\n height: h1,\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n clonedSvg = null as any;\n\n return result;\n}\n\nconst LEGEND_TEXT_STYLE_PROPERTIES_MAP = {\n color: 'fill',\n 'font-family': 'font-family',\n 'font-size': 'font-size',\n 'font-weight': 'font-weight',\n};\n\nexport function cloneLegendsToSVG(\n legends: Legend[],\n svgWidth: number,\n config: {\n selectedLegends: Record<string, boolean>;\n centerLegends: boolean;\n textClassName: string;\n isRTL: boolean;\n },\n legendContainer?: HTMLElement | null,\n): {\n node: SVGGElement | null;\n width: number;\n height: number;\n} {\n if (legends.length === 0) {\n return {\n node: null,\n width: 0,\n height: 0,\n };\n }\n\n const { selectedLegends, centerLegends, textClassName, isRTL } = config;\n const legendGroup = d3Create<SVGGElement>('svg:g');\n let legendX = centerLegends ? 0 : LEGEND_CONTAINER_MARGIN_START;\n let legendY = LEGEND_CONTAINER_MARGIN_TOP;\n let legendLine: { elem: Selection<SVGGElement, unknown, null, undefined>; width: number }[] = [];\n const legendLines: (typeof legendLine)[] = [];\n const legendLineWidths: number[] = [];\n const noLegendsSelected = Object.keys(selectedLegends).length === 0;\n\n for (let i = 0; i < legends.length; i++) {\n const textOffset = LEGEND_PADDING + LEGEND_SHAPE_SIZE + LEGEND_SHAPE_MARGIN_END;\n const legendText = createMeasurementSpan(legends[i].title, textClassName, legendContainer);\n const legendWidth = textOffset + legendText.getBoundingClientRect().width + LEGEND_PADDING;\n const legendItem = legendGroup.append('g');\n\n legendLine.push({ elem: legendItem, width: legendWidth });\n if (legendX + legendWidth > svgWidth && legendLine.length > 1) {\n legendLine.pop();\n legendLines.push(legendLine);\n legendLineWidths.push(legendX);\n\n legendLine = [{ elem: legendItem, width: legendWidth }];\n legendX = centerLegends ? 0 : LEGEND_CONTAINER_MARGIN_START;\n legendY += LEGEND_HEIGHT;\n }\n\n const isLegendActive = selectedLegends[legends[i].title] || noLegendsSelected;\n\n legendItem\n .append('rect')\n .attr('x', legendX + (isRTL ? legendWidth - LEGEND_PADDING - LEGEND_SHAPE_SIZE : LEGEND_PADDING))\n .attr('y', legendY + LEGEND_PADDING)\n .attr('width', LEGEND_SHAPE_SIZE)\n .attr('height', LEGEND_SHAPE_SIZE)\n .style('fill', isLegendActive ? legends[i].color : 'transparent')\n .style('stroke-width', LEGEND_SHAPE_BORDER)\n .style('stroke', legends[i].color);\n\n legendItem\n .append('text')\n .attr('x', legendX + (isRTL ? legendWidth - textOffset : textOffset))\n .attr('y', legendY + LEGEND_PADDING)\n .attr('dominant-baseline', 'hanging')\n .style('opacity', isLegendActive ? 1 : INACTIVE_LEGEND_TEXT_OPACITY)\n .text(legends[i].title)\n .call(selection => copyStyle(LEGEND_TEXT_STYLE_PROPERTIES_MAP, legendText, selection.node()!));\n\n legendX += legendWidth;\n }\n\n legendLines.push(legendLine);\n legendLineWidths.push(legendX);\n legendY += LEGEND_HEIGHT;\n\n if (centerLegends) {\n legendLines.forEach((ln, idx) => {\n const lineOffsetX = Math.max((svgWidth - legendLineWidths[idx]) / 2, 0);\n let remLineWidth = legendLineWidths[idx];\n let itemOffsetX = 0;\n ln.forEach(item => {\n const newOffsetX = lineOffsetX + (isRTL ? remLineWidth - item.width - itemOffsetX : 0);\n item.elem.attr('transform', `translate(${newOffsetX}, 0)`);\n remLineWidth -= item.width;\n itemOffsetX += item.width;\n });\n });\n } else if (isRTL) {\n const w1 = Math.max(svgWidth, ...legendLineWidths);\n legendLines.forEach(ln => {\n let remLineWidth = w1 - LEGEND_CONTAINER_MARGIN_START;\n let itemOffsetX = LEGEND_CONTAINER_MARGIN_START;\n ln.forEach(item => {\n const newOffsetX = remLineWidth - item.width - itemOffsetX;\n item.elem.attr('transform', `translate(${newOffsetX}, 0)`);\n remLineWidth -= item.width;\n itemOffsetX += item.width;\n });\n });\n }\n\n return {\n node: legendGroup.node(),\n width: Math.max(...legendLineWidths),\n height: legendY,\n };\n}\n\nfunction svgToPng(svgDataUrl: string, opts: ImageExportOptions = {}): Promise<string> {\n return new Promise((resolve, reject) => {\n const scale = opts.scale || 1;\n const w0 = opts.width || 300;\n const h0 = opts.height || 150;\n const w1 = scale * w0;\n const h1 = scale * h0;\n\n const canvas = document.createElement('canvas');\n const img = new Image();\n\n canvas.width = w1;\n canvas.height = h1;\n\n img.onload = function () {\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n return reject(new Error('Canvas context is null'));\n }\n\n ctx.clearRect(0, 0, w1, h1);\n ctx.drawImage(img, 0, 0, w1, h1);\n\n const imgData = canvas.toDataURL('image/png');\n resolve(imgData);\n };\n\n img.onerror = function (err) {\n reject(err);\n };\n\n img.src = svgDataUrl;\n });\n}\n\nconst hex2 = /^[\\da-f]{2}$/i;\nconst hex4 = /^[\\da-f]{4}$/i;\n\n/**\n * A ponyfill for the deprecated `unescape` method, taken from the `core-js` library.\n *\n * Source: {@link https://github.com/zloirock/core-js/blob/167136f479d3b8519953f2e4c534ecdd1031d3cf/packages/core-js/modules/es.unescape.js core-js/packages/core-js/modules/es.unescape.js}\n */\nfunction unescapePonyfill(str: string) {\n let result = '';\n const length = str.length;\n let index = 0;\n let chr;\n let part;\n while (index < length) {\n chr = str.charAt(index++);\n if (chr === '%') {\n if (str.charAt(index) === 'u') {\n part = str.slice(index + 1, index + 5);\n if (hex4.exec(part)) {\n result += String.fromCharCode(parseInt(part, 16));\n index += 5;\n continue;\n }\n } else {\n part = str.slice(index, index + 2);\n if (hex2.exec(part)) {\n result += String.fromCharCode(parseInt(part, 16));\n index += 2;\n continue;\n }\n }\n }\n result += chr;\n }\n return result;\n}\n"],"names":["create","d3Create","select","d3Select","isHTMLElement","copyStyle","createMeasurementSpan","resolveCSSVariables","LEGEND_CONTAINER_MARGIN_TOP","LEGEND_CONTAINER_MARGIN_START","LEGEND_PADDING","LEGEND_HEIGHT","LEGEND_SHAPE_BORDER","LEGEND_SHAPE_SIZE","LEGEND_SHAPE_MARGIN_END","INACTIVE_LEGEND_TEXT_OPACITY","toImage","chartContainer","legendsToSvgCallback","isRTL","opts","Promise","resolve","reject","Error","background","svg","toSVG","node","svgData","XMLSerializer","serializeToString","svgDataUrl","btoa","unescapePonyfill","encodeURIComponent","svgToPng","width","height","scale","then","catch","err","SVG_STYLE_PROPERTIES","SVG_TEXT_STYLE_PROPERTIES","ANNOTATION_HTML_STYLE_PROPERTIES","ANNOTATION_FOREIGN_OBJECT_STYLE_PROPERTIES","querySelector","clonedSvg","cloneNode","attr","svgElements","getElementsByTagName","clonedSvgElements","TEXT_ELEMENTS","TABLE_ELEMENTS","i","length","tag","tagName","toLowerCase","includes","originalForeignObjects","querySelectorAll","clonedForeignObjects","forEach","originalFo","index","clonedFo","originalRoot","firstElementChild","clonedRoot","originalHtmlElements","clonedHtmlElements","originalEl","elementIndex","clonedEl","svgWidth","svgHeight","getBoundingClientRect","legendGroup","w1","Math","max","h1","annotationSvg","annotationClone","annotationElements","clonedAnnotationElements","original","cloned","isSvgElement","SVGElement","isTextElement","isHtmlElement","append","insert","selectAll","remove","result","LEGEND_TEXT_STYLE_PROPERTIES_MAP","color","cloneLegendsToSVG","legends","config","legendContainer","selectedLegends","centerLegends","textClassName","legendX","legendY","legendLine","legendLines","legendLineWidths","noLegendsSelected","Object","keys","textOffset","legendText","title","legendWidth","legendItem","push","elem","pop","isLegendActive","style","text","call","selection","ln","idx","lineOffsetX","remLineWidth","itemOffsetX","item","newOffsetX","w0","h0","canvas","document","createElement","img","Image","onload","ctx","getContext","clearRect","drawImage","imgData","toDataURL","onerror","src","hex2","hex4","str","chr","part","charAt","slice","exec","String","fromCharCode","parseInt"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ const _export_star = require("@swc/helpers/_/_export_star");
6
+ _export_star._(require("./components/AnnotationOnlyChart/index"), exports);
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/AnnotationOnlyChart.ts"],"sourcesContent":["export * from './components/AnnotationOnlyChart/index';\n"],"names":[],"mappings":";;;;;uBAAc,yCAAyC"}
@@ -0,0 +1,219 @@
1
+ 'use client';
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "AnnotationOnlyChart", {
7
+ enumerable: true,
8
+ get: function() {
9
+ return AnnotationOnlyChart;
10
+ }
11
+ });
12
+ const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
13
+ const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
14
+ const _ChartAnnotationLayer = require("../CommonComponents/Annotations/ChartAnnotationLayer");
15
+ const _imageexportutils = require("../../utilities/image-export-utils");
16
+ const _utilities = require("../../utilities");
17
+ const _useAnnotationOnlyChartStylesstyles = require("./useAnnotationOnlyChartStyles.styles");
18
+ const DEFAULT_HEIGHT = 650;
19
+ const FALLBACK_WIDTH = 400;
20
+ const buildPadding = (margin)=>{
21
+ if (!margin) {
22
+ return undefined;
23
+ }
24
+ var _margin_t;
25
+ const top = (_margin_t = margin.t) !== null && _margin_t !== void 0 ? _margin_t : 0;
26
+ var _margin_r;
27
+ const right = (_margin_r = margin.r) !== null && _margin_r !== void 0 ? _margin_r : 0;
28
+ var _margin_b;
29
+ const bottom = (_margin_b = margin.b) !== null && _margin_b !== void 0 ? _margin_b : 0;
30
+ var _margin_l;
31
+ const left = (_margin_l = margin.l) !== null && _margin_l !== void 0 ? _margin_l : 0;
32
+ if (top === 0 && right === 0 && bottom === 0 && left === 0) {
33
+ return undefined;
34
+ }
35
+ return `${top}px ${right}px ${bottom}px ${left}px`;
36
+ };
37
+ const AnnotationOnlyChart = (props)=>{
38
+ const { annotations, chartTitle, description, width, height, paperBackgroundColor, plotBackgroundColor, fontColor, fontFamily, margin, componentRef } = props;
39
+ const isRtl = (0, _utilities.useRtl)();
40
+ const classes = (0, _useAnnotationOnlyChartStylesstyles.useAnnotationOnlyChartStyles)();
41
+ const containerRef = _react.useRef(null);
42
+ const contentRef = _react.useRef(null);
43
+ const [measuredWidth, setMeasuredWidth] = _react.useState(width !== null && width !== void 0 ? width : 0);
44
+ const [contentHeight, setContentHeight] = _react.useState(height !== null && height !== void 0 ? height : DEFAULT_HEIGHT);
45
+ _react.useEffect(()=>{
46
+ if (typeof width === 'number' && width > 0) {
47
+ setMeasuredWidth(width);
48
+ return;
49
+ }
50
+ const node = containerRef.current;
51
+ if (!node || typeof ResizeObserver === 'undefined') {
52
+ const rect = node === null || node === void 0 ? void 0 : node.getBoundingClientRect();
53
+ if (rect && rect.width > 0) {
54
+ setMeasuredWidth(rect.width);
55
+ } else {
56
+ setMeasuredWidth((prev)=>prev > 0 ? prev : FALLBACK_WIDTH);
57
+ }
58
+ return;
59
+ }
60
+ const observer = new ResizeObserver((entries)=>{
61
+ const entry = entries[0];
62
+ if (!entry) {
63
+ return;
64
+ }
65
+ const newWidth = entry.contentRect.width;
66
+ if (newWidth > 0 && Math.abs(newWidth - measuredWidth) > 0.5) {
67
+ setMeasuredWidth(newWidth);
68
+ }
69
+ });
70
+ const rect = node.getBoundingClientRect();
71
+ if (rect.width > 0) {
72
+ setMeasuredWidth(rect.width);
73
+ }
74
+ observer.observe(node);
75
+ return ()=>observer.disconnect();
76
+ }, [
77
+ width,
78
+ measuredWidth
79
+ ]);
80
+ const resolvedWidth = Math.max(measuredWidth || FALLBACK_WIDTH, 1);
81
+ const resolvedHeight = Math.max(height !== null && height !== void 0 ? height : DEFAULT_HEIGHT, 1);
82
+ _react.useEffect(()=>{
83
+ const node = contentRef.current;
84
+ if (!node) {
85
+ setContentHeight((prev)=>prev > 0 ? prev : resolvedHeight);
86
+ return;
87
+ }
88
+ if (typeof ResizeObserver === 'undefined') {
89
+ const rect = node.getBoundingClientRect();
90
+ setContentHeight((prev)=>rect.height > 0 ? rect.height : prev > 0 ? prev : resolvedHeight);
91
+ return;
92
+ }
93
+ const observer = new ResizeObserver((entries)=>{
94
+ const entry = entries[0];
95
+ if (!entry) {
96
+ return;
97
+ }
98
+ const newHeight = entry.contentRect.height;
99
+ if (newHeight > 0) {
100
+ setContentHeight((prev)=>Math.abs(prev - newHeight) > 0.5 ? newHeight : prev);
101
+ }
102
+ });
103
+ const rect = node.getBoundingClientRect();
104
+ setContentHeight((prev)=>rect.height > 0 ? rect.height : prev > 0 ? prev : resolvedHeight);
105
+ observer.observe(node);
106
+ return ()=>observer.disconnect();
107
+ }, [
108
+ resolvedHeight,
109
+ resolvedWidth,
110
+ annotations,
111
+ chartTitle,
112
+ description,
113
+ margin,
114
+ plotBackgroundColor,
115
+ paperBackgroundColor,
116
+ fontColor,
117
+ fontFamily
118
+ ]);
119
+ const svgHeight = Math.max(Math.ceil(contentHeight || 0), resolvedHeight);
120
+ const context = {
121
+ plotRect: {
122
+ x: 0,
123
+ y: 0,
124
+ width: resolvedWidth,
125
+ height: resolvedHeight
126
+ },
127
+ svgRect: {
128
+ width: resolvedWidth,
129
+ height: resolvedHeight
130
+ },
131
+ isRtl
132
+ };
133
+ const padding = buildPadding(margin);
134
+ // Inline styles for dynamic values that can't be in makeStyles
135
+ const rootStyle = _react.useMemo(()=>({
136
+ width: width ? `${width}px` : '100%',
137
+ minHeight: resolvedHeight,
138
+ ...paperBackgroundColor && {
139
+ backgroundColor: paperBackgroundColor
140
+ },
141
+ ...fontColor && {
142
+ color: fontColor
143
+ },
144
+ ...fontFamily && {
145
+ fontFamily
146
+ },
147
+ ...padding && {
148
+ padding
149
+ }
150
+ }), [
151
+ fontColor,
152
+ fontFamily,
153
+ paperBackgroundColor,
154
+ padding,
155
+ resolvedHeight,
156
+ width
157
+ ]);
158
+ const contentStyle = _react.useMemo(()=>({
159
+ ...plotBackgroundColor && {
160
+ backgroundColor: plotBackgroundColor
161
+ }
162
+ }), [
163
+ plotBackgroundColor
164
+ ]);
165
+ const resolvedAnnotations = annotations !== null && annotations !== void 0 ? annotations : [];
166
+ const hasAnnotations = resolvedAnnotations.length > 0;
167
+ const ariaLabel = hasAnnotations ? description !== null && description !== void 0 ? description : chartTitle : undefined;
168
+ _react.useImperativeHandle(componentRef, ()=>{
169
+ const chartHandle = {
170
+ chartContainer: containerRef.current,
171
+ toImage: (opts)=>{
172
+ if (!containerRef.current) {
173
+ return Promise.reject(new Error('Chart container is not defined'));
174
+ }
175
+ return (0, _imageexportutils.toImage)(containerRef.current, undefined, isRtl, opts);
176
+ }
177
+ };
178
+ return chartHandle;
179
+ }, [
180
+ isRtl
181
+ ]);
182
+ return /*#__PURE__*/ _react.createElement("div", {
183
+ ref: containerRef,
184
+ "data-chart-annotation-container": "true"
185
+ }, /*#__PURE__*/ _react.createElement("svg", {
186
+ width: resolvedWidth,
187
+ height: svgHeight,
188
+ viewBox: `0 0 ${resolvedWidth} ${svgHeight}`,
189
+ style: {
190
+ width: width ? `${width}px` : '100%',
191
+ height: `${svgHeight}px`,
192
+ display: 'block'
193
+ },
194
+ role: ariaLabel ? 'img' : undefined,
195
+ "aria-label": ariaLabel
196
+ }, /*#__PURE__*/ _react.createElement("foreignObject", {
197
+ x: 0,
198
+ y: 0,
199
+ width: resolvedWidth,
200
+ height: svgHeight
201
+ }, /*#__PURE__*/ _react.createElement("div", {
202
+ ref: contentRef,
203
+ className: classes.root,
204
+ style: rootStyle,
205
+ "data-chart-annotation-only": "true",
206
+ "aria-label": ariaLabel
207
+ }, chartTitle && /*#__PURE__*/ _react.createElement("span", {
208
+ className: classes.title,
209
+ "aria-hidden": "true"
210
+ }, chartTitle), /*#__PURE__*/ _react.createElement("div", {
211
+ className: classes.content,
212
+ style: contentStyle,
213
+ role: "presentation"
214
+ }, hasAnnotations ? /*#__PURE__*/ _react.createElement(_ChartAnnotationLayer.ChartAnnotationLayer, {
215
+ annotations: resolvedAnnotations,
216
+ context: context
217
+ }) : null)))));
218
+ };
219
+ AnnotationOnlyChart.displayName = 'AnnotationOnlyChart';