@monolith-forensics/monolith-ui 1.8.1-dev.4 → 1.8.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 (170) hide show
  1. package/dist/Button/Button.js +58 -9
  2. package/dist/Calendar/Calendar.d.ts +2 -7
  3. package/dist/Calendar/Calendar.js +49 -226
  4. package/dist/Calendar/CalendarStyles.d.ts +2 -6
  5. package/dist/Calendar/CalendarStyles.js +33 -153
  6. package/dist/Calendar/calendarHelpers.d.ts +2 -6
  7. package/dist/Calendar/calendarHelpers.js +5 -13
  8. package/dist/Charts/BarChart/BarChart.js +28 -14
  9. package/dist/Charts/BarChart/BarChart.styled.d.ts +7 -2
  10. package/dist/Charts/BarChart/BarChart.styled.js +5 -1
  11. package/dist/Charts/BarChart/BarChart.types.d.ts +13 -5
  12. package/dist/Charts/ChartUtils/chartSizing.d.ts +20 -0
  13. package/dist/Charts/ChartUtils/chartSizing.js +83 -0
  14. package/dist/Charts/ChartUtils/index.d.ts +1 -0
  15. package/dist/Charts/ChartUtils/index.js +1 -0
  16. package/dist/Charts/HeatMap/HeatMap.js +28 -7
  17. package/dist/Charts/HeatMap/HeatMap.styled.d.ts +6 -2
  18. package/dist/Charts/HeatMap/HeatMap.styled.js +3 -0
  19. package/dist/Charts/HeatMap/HeatMap.types.d.ts +7 -1
  20. package/dist/Charts/LineChart/LineChart.js +34 -15
  21. package/dist/Charts/LineChart/LineChart.styled.d.ts +7 -2
  22. package/dist/Charts/LineChart/LineChart.styled.js +5 -1
  23. package/dist/Charts/LineChart/LineChart.types.d.ts +13 -5
  24. package/dist/Charts/PieChart/PieChart.js +48 -33
  25. package/dist/Charts/PieChart/PieChart.styled.d.ts +7 -2
  26. package/dist/Charts/PieChart/PieChart.styled.js +6 -1
  27. package/dist/Charts/PieChart/PieChart.types.d.ts +7 -3
  28. package/dist/CheckBox/CheckBox.js +19 -36
  29. package/dist/DateInput/DateInput.js +143 -198
  30. package/dist/DropDownMenu/DropDownMenu.js +15 -25
  31. package/dist/DropDownMenu/components/MenuComponent.js +2 -8
  32. package/dist/DropDownMenu/components/MenuItem.d.ts +0 -2
  33. package/dist/DropDownMenu/components/MenuItem.js +21 -25
  34. package/dist/DropDownMenu/components/MenuItemList.d.ts +0 -3
  35. package/dist/DropDownMenu/components/MenuItemList.js +86 -192
  36. package/dist/DropDownMenu/components/StyledContent.js +2 -1
  37. package/dist/DropDownMenu/components/StyledFloatContainer.js +1 -1
  38. package/dist/DropDownMenu/types.d.ts +0 -3
  39. package/dist/FieldLabel/FieldLabel.js +12 -4
  40. package/dist/FileInputField/FileInputField.js +23 -4
  41. package/dist/FileViewer/viewers/ImageViewer.js +18 -75
  42. package/dist/FormSection/FormSection.js +25 -5
  43. package/dist/IconButton/IconButton.js +16 -2
  44. package/dist/Input/Input.js +56 -7
  45. package/dist/MonolithUIProvider/MonolithUIProvider.d.ts +4 -1
  46. package/dist/Pill/Pill.js +79 -8
  47. package/dist/Popover/Popover.context.d.ts +1 -2
  48. package/dist/Popover/Popover.js +2 -5
  49. package/dist/Popover/Popover.styles.d.ts +6 -1
  50. package/dist/Popover/Popover.styles.js +28 -11
  51. package/dist/Popover/Popover.transitions.d.ts +2 -4
  52. package/dist/Popover/Popover.transitions.js +49 -23
  53. package/dist/Popover/PopoverDropdown.js +8 -6
  54. package/dist/Popover/PopoverTarget.js +3 -6
  55. package/dist/QueryFilter/DefaultOperators.d.ts +76 -0
  56. package/dist/QueryFilter/DefaultOperators.js +21 -0
  57. package/dist/QueryFilter/QueryFilter.d.ts +1 -1
  58. package/dist/QueryFilter/QueryFilter.js +303 -3
  59. package/dist/QueryFilter/index.d.ts +2 -3
  60. package/dist/QueryFilter/index.js +2 -3
  61. package/dist/QueryFilter/types.d.ts +52 -0
  62. package/dist/QueryFilter/types.js +1 -0
  63. package/dist/QueryFilter/useQueryFilter.d.ts +1 -1
  64. package/dist/QueryFilter/useQueryFilter.js +19 -23
  65. package/dist/RichTextEditor/Components/CodeBlockBaseButton.d.ts +18 -0
  66. package/dist/RichTextEditor/Components/CodeBlockBaseButton.js +6 -0
  67. package/dist/RichTextEditor/Components/CodeBlockCopyButton.d.ts +9 -0
  68. package/dist/RichTextEditor/Components/CodeBlockCopyButton.js +42 -0
  69. package/dist/RichTextEditor/Components/CodeBlockFormatButton.d.ts +10 -0
  70. package/dist/RichTextEditor/Components/CodeBlockFormatButton.js +60 -0
  71. package/dist/RichTextEditor/Components/CodeBlockLanguageSelect.d.ts +9 -0
  72. package/dist/RichTextEditor/Components/CodeBlockLanguageSelect.js +30 -0
  73. package/dist/RichTextEditor/Components/CodeBlockNodeView.d.ts +3 -0
  74. package/dist/RichTextEditor/Components/CodeBlockNodeView.js +28 -0
  75. package/dist/RichTextEditor/Components/CodeBlockWrapButton.d.ts +10 -0
  76. package/dist/RichTextEditor/Components/CodeBlockWrapButton.js +17 -0
  77. package/dist/RichTextEditor/Components/LinkEditor.d.ts +8 -0
  78. package/dist/RichTextEditor/Components/LinkEditor.js +94 -0
  79. package/dist/RichTextEditor/Components/TableTools/TableCornerMenu.d.ts +2 -0
  80. package/dist/RichTextEditor/Components/TableTools/TableCornerMenu.js +19 -0
  81. package/dist/RichTextEditor/Components/TableTools/TableInsertControls.d.ts +2 -0
  82. package/dist/RichTextEditor/Components/TableTools/TableInsertControls.js +24 -0
  83. package/dist/RichTextEditor/Components/TableTools/TableRails.d.ts +2 -0
  84. package/dist/RichTextEditor/Components/TableTools/TableRails.js +180 -0
  85. package/dist/RichTextEditor/Components/TableTools/TableToolMenu.d.ts +5 -0
  86. package/dist/RichTextEditor/Components/TableTools/TableToolMenu.js +6 -0
  87. package/dist/RichTextEditor/Components/TableTools/TableTools.actions.d.ts +5 -0
  88. package/dist/RichTextEditor/Components/TableTools/TableTools.actions.js +183 -0
  89. package/dist/RichTextEditor/Components/TableTools/TableTools.commands.d.ts +16 -0
  90. package/dist/RichTextEditor/Components/TableTools/TableTools.commands.js +217 -0
  91. package/dist/RichTextEditor/Components/TableTools/TableTools.constants.d.ts +8 -0
  92. package/dist/RichTextEditor/Components/TableTools/TableTools.constants.js +11 -0
  93. package/dist/RichTextEditor/Components/TableTools/TableTools.d.ts +3 -0
  94. package/dist/RichTextEditor/Components/TableTools/TableTools.geometry.d.ts +23 -0
  95. package/dist/RichTextEditor/Components/TableTools/TableTools.geometry.js +75 -0
  96. package/dist/RichTextEditor/Components/TableTools/TableTools.js +3 -0
  97. package/dist/RichTextEditor/Components/TableTools/TableTools.selectors.d.ts +16 -0
  98. package/dist/RichTextEditor/Components/TableTools/TableTools.selectors.js +53 -0
  99. package/dist/RichTextEditor/Components/TableTools/TableTools.styled.d.ts +40 -0
  100. package/dist/RichTextEditor/Components/TableTools/TableTools.styled.js +167 -0
  101. package/dist/RichTextEditor/Components/TableTools/TableTools.types.d.ts +76 -0
  102. package/dist/RichTextEditor/Components/TableTools/TableTools.types.js +1 -0
  103. package/dist/RichTextEditor/Components/TableTools/TableTools.utils.d.ts +4 -0
  104. package/dist/RichTextEditor/Components/TableTools/TableTools.utils.js +4 -0
  105. package/dist/RichTextEditor/Components/TableTools/TableToolsPopover.d.ts +2 -0
  106. package/dist/RichTextEditor/Components/TableTools/TableToolsPopover.js +12 -0
  107. package/dist/RichTextEditor/Components/TableTools/index.d.ts +3 -0
  108. package/dist/RichTextEditor/Components/TableTools/index.js +2 -0
  109. package/dist/RichTextEditor/Enums/HighlightColors.d.ts +9 -0
  110. package/dist/RichTextEditor/Enums/HighlightColors.js +10 -0
  111. package/dist/RichTextEditor/Extensions/getTiptapExtensions.js +15 -5
  112. package/dist/RichTextEditor/Plugins/ImageActionsPlugin.js +4 -7
  113. package/dist/RichTextEditor/Plugins/UploadImagesPlugin.d.ts +0 -15
  114. package/dist/RichTextEditor/Plugins/UploadImagesPlugin.js +51 -115
  115. package/dist/RichTextEditor/Plugins/index.d.ts +0 -1
  116. package/dist/RichTextEditor/Plugins/index.js +0 -1
  117. package/dist/RichTextEditor/RichTextEditor.d.ts +2 -3
  118. package/dist/RichTextEditor/RichTextEditor.js +35 -309
  119. package/dist/RichTextEditor/Toolbar/Toolbar.js +2 -14
  120. package/dist/RichTextEditor/Utils/codeBlockUtils.d.ts +20 -0
  121. package/dist/RichTextEditor/Utils/codeBlockUtils.js +137 -0
  122. package/dist/RichTextEditor/Utils/codeUtils.d.ts +3 -0
  123. package/dist/RichTextEditor/Utils/codeUtils.js +12 -0
  124. package/dist/RichTextEditor/Utils/linkUtils.d.ts +19 -0
  125. package/dist/RichTextEditor/Utils/linkUtils.js +57 -0
  126. package/dist/RichTextEditor/Utils/tableUtils.d.ts +1 -0
  127. package/dist/RichTextEditor/Utils/tableUtils.js +1 -0
  128. package/dist/SegmentedControl/SegmentedControl.utils.d.ts +2 -2
  129. package/dist/SegmentedControl/SegmentedControl.utils.js +30 -3
  130. package/dist/SelectBox/SelectBox.js +5 -5
  131. package/dist/SelectBox/select-box.styled-components.d.ts +1 -4
  132. package/dist/SelectBox/select-box.styled-components.js +48 -11
  133. package/dist/SelectBox/types.d.ts +0 -1
  134. package/dist/Switch/Switch.d.ts +2 -2
  135. package/dist/Switch/Switch.js +83 -18
  136. package/dist/Table/ColumnResizer.d.ts +9 -6
  137. package/dist/Table/ColumnResizer.js +10 -30
  138. package/dist/Table/StateStorage.d.ts +0 -4
  139. package/dist/Table/StateStorage.js +0 -13
  140. package/dist/Table/Table.js +12 -160
  141. package/dist/Table/TableComponents.d.ts +0 -10
  142. package/dist/Table/TableComponents.js +10 -71
  143. package/dist/Table/TableDefaults.d.ts +0 -7
  144. package/dist/Table/TableDefaults.js +0 -7
  145. package/dist/Table/TableHeader.js +16 -31
  146. package/dist/Table/TableMenu/TableMenu.js +1 -1
  147. package/dist/Table/TableProvider.js +75 -354
  148. package/dist/Table/TableRow.js +16 -28
  149. package/dist/Table/Utils/index.d.ts +1 -0
  150. package/dist/Table/Utils/index.js +1 -0
  151. package/dist/Table/Utils/resizeHandler.d.ts +3 -0
  152. package/dist/Table/Utils/resizeHandler.js +84 -0
  153. package/dist/Table/types.d.ts +19 -70
  154. package/dist/TagBox/TagBox.d.ts +1 -1
  155. package/dist/TagBox/TagBox.js +80 -22
  156. package/dist/TagBox/types.d.ts +0 -1
  157. package/dist/TextArea/TextArea.js +23 -9
  158. package/dist/TextInput/TextInput.js +6 -12
  159. package/dist/Utilities/parseTimestamp.js +6 -11
  160. package/dist/core/ArrowButton.d.ts +0 -2
  161. package/dist/core/ArrowButton.js +3 -7
  162. package/dist/core/ClearButton.d.ts +0 -2
  163. package/dist/core/ClearButton.js +3 -7
  164. package/dist/core/controlSizes.js +9 -9
  165. package/dist/core/index.d.ts +0 -1
  166. package/dist/core/index.js +0 -1
  167. package/dist/index.d.ts +0 -3
  168. package/dist/index.js +0 -2
  169. package/dist/theme/variants.js +8 -2
  170. package/package.json +18 -26
@@ -0,0 +1,83 @@
1
+ import { useEffect, useMemo, useState } from "react";
2
+ const toDimensionStyle = (dimension) => {
3
+ if (dimension == null || typeof dimension === "number")
4
+ return undefined;
5
+ return dimension;
6
+ };
7
+ const toNumericDimension = (dimension, fallback) => typeof dimension === "number" && Number.isFinite(dimension)
8
+ ? dimension
9
+ : fallback;
10
+ const getElementSize = (element) => {
11
+ const rect = element.getBoundingClientRect();
12
+ return {
13
+ width: Math.max(Math.round(rect.width || element.clientWidth || 0), 0),
14
+ height: Math.max(Math.round(rect.height || element.clientHeight || 0), 0),
15
+ };
16
+ };
17
+ export const useChartResponsiveSize = (ref, { width, height, responsive = false, aspectRatio, defaultWidth, defaultHeight, minWidth, minHeight, }) => {
18
+ const resolvedWidthInput = width !== null && width !== void 0 ? width : (responsive ? "100%" : defaultWidth);
19
+ const resolvedHeightInput = height !== null && height !== void 0 ? height : defaultHeight;
20
+ const shouldMeasureWidth = responsive || typeof resolvedWidthInput === "string";
21
+ const shouldMeasureHeight = typeof resolvedHeightInput === "string";
22
+ const shouldMeasure = shouldMeasureWidth || shouldMeasureHeight;
23
+ const [measuredSize, setMeasuredSize] = useState({ width: 0, height: 0 });
24
+ useEffect(() => {
25
+ if (!shouldMeasure)
26
+ return;
27
+ const element = ref.current;
28
+ if (!element)
29
+ return;
30
+ const updateSize = () => {
31
+ const nextSize = getElementSize(element);
32
+ setMeasuredSize((currentSize) => currentSize.width === nextSize.width &&
33
+ currentSize.height === nextSize.height
34
+ ? currentSize
35
+ : nextSize);
36
+ };
37
+ updateSize();
38
+ if (typeof ResizeObserver === "undefined") {
39
+ window.addEventListener("resize", updateSize);
40
+ return () => window.removeEventListener("resize", updateSize);
41
+ }
42
+ const observer = new ResizeObserver(updateSize);
43
+ observer.observe(element);
44
+ return () => observer.disconnect();
45
+ }, [ref, shouldMeasure]);
46
+ return useMemo(() => {
47
+ const fallbackWidth = toNumericDimension(resolvedWidthInput, defaultWidth);
48
+ const fallbackHeight = toNumericDimension(resolvedHeightInput, defaultHeight);
49
+ const measuredWidth = shouldMeasureWidth && measuredSize.width > 0
50
+ ? measuredSize.width
51
+ : fallbackWidth;
52
+ const safeWidth = Math.max(measuredWidth, minWidth);
53
+ const resolvedAspectRatio = aspectRatio != null && Number.isFinite(aspectRatio) && aspectRatio > 0
54
+ ? aspectRatio
55
+ : null;
56
+ const measuredHeight = height == null && resolvedAspectRatio != null
57
+ ? safeWidth / resolvedAspectRatio
58
+ : shouldMeasureHeight && measuredSize.height > 0
59
+ ? measuredSize.height
60
+ : fallbackHeight;
61
+ return {
62
+ width: Math.max(Math.round(safeWidth), minWidth),
63
+ height: Math.max(Math.round(measuredHeight), minHeight),
64
+ widthStyle: toDimensionStyle(resolvedWidthInput),
65
+ heightStyle: toDimensionStyle(resolvedHeightInput),
66
+ fillAvailableWidth: responsive || typeof resolvedWidthInput === "string",
67
+ };
68
+ }, [
69
+ aspectRatio,
70
+ defaultHeight,
71
+ defaultWidth,
72
+ height,
73
+ measuredSize.height,
74
+ measuredSize.width,
75
+ minHeight,
76
+ minWidth,
77
+ resolvedHeightInput,
78
+ resolvedWidthInput,
79
+ responsive,
80
+ shouldMeasureHeight,
81
+ shouldMeasureWidth,
82
+ ]);
83
+ };
@@ -1,3 +1,4 @@
1
1
  export * from "./chartColors";
2
2
  export * from "./chartExport";
3
3
  export * from "./chartMath";
4
+ export * from "./chartSizing";
@@ -1,3 +1,4 @@
1
1
  export * from "./chartColors";
2
2
  export * from "./chartExport";
3
3
  export * from "./chartMath";
4
+ export * from "./chartSizing";
@@ -22,14 +22,15 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
22
22
  import { forwardRef, useEffect, useId, useImperativeHandle, useMemo, useRef, useState, } from "react";
23
23
  import { useTheme } from "styled-components";
24
24
  import { ChartExportControl } from "../ChartPrimitives";
25
- import { DEFAULT_CHART_EXPORT_FORMATS, copyChartImage, downloadChartImage, } from "../ChartUtils";
25
+ import { DEFAULT_CHART_EXPORT_FORMATS, copyChartImage, downloadChartImage, useChartResponsiveSize, } from "../ChartUtils";
26
26
  import { buildHeatMapCells, clamp, easeOutCubic, formatDefaultValue, formatDefaultWeekdayLabel, getHeatMapColor, getHeatMapDateRange, getMonthLabels, } from "./HeatMap.lib";
27
27
  import { StyledCell, StyledChartActions, StyledChartFrame, StyledChartScroller, StyledContainer, StyledLegend, StyledLegendCell, StyledLegendScale, StyledMonthLabel, StyledSvg, StyledTooltip, StyledTooltipHeader, StyledTooltipMeta, StyledTooltipSwatch, StyledWeekdayLabel, } from "./HeatMap.styled";
28
28
  const HeatMapInner = (_a, ref) => {
29
- var { data, startDate, endDate, cellSize = 12, cellGap = 4, cellRadius = 2, emptyColor, colors, minValue = 0, maxValue, weekStartsOn = 0, showMonthLabels = true, showWeekdayLabels = true, showLegend = true, animateOnRender = false, animationDuration = 350, animationStagger = 1, showExportButton = false, exportFileName = "heat-map", exportFormats = DEFAULT_CHART_EXPORT_FORMATS, exportScale = 2, exportBackgroundColor, showTooltips = false, ariaLabel = "Heat map", valueFormatter, monthLabelFormatter, weekdayLabelFormatter, tooltipFormatter, onCellClick, className } = _a, props = __rest(_a, ["data", "startDate", "endDate", "cellSize", "cellGap", "cellRadius", "emptyColor", "colors", "minValue", "maxValue", "weekStartsOn", "showMonthLabels", "showWeekdayLabels", "showLegend", "animateOnRender", "animationDuration", "animationStagger", "showExportButton", "exportFileName", "exportFormats", "exportScale", "exportBackgroundColor", "showTooltips", "ariaLabel", "valueFormatter", "monthLabelFormatter", "weekdayLabelFormatter", "tooltipFormatter", "onCellClick", "className"]);
29
+ var { data, width, responsive = false, startDate, endDate, cellSize = 12, minCellSize = 6, cellGap = 4, cellRadius = 2, emptyColor, colors, minValue = 0, maxValue, weekStartsOn = 0, showMonthLabels = true, showWeekdayLabels = true, showLegend = true, animateOnRender = false, animationDuration = 350, animationStagger = 1, showExportButton = false, exportFileName = "heat-map", exportFormats = DEFAULT_CHART_EXPORT_FORMATS, exportScale = 2, exportBackgroundColor, showTooltips = false, ariaLabel = "Heat map", valueFormatter, monthLabelFormatter, weekdayLabelFormatter, tooltipFormatter, onCellClick, className } = _a, props = __rest(_a, ["data", "width", "responsive", "startDate", "endDate", "cellSize", "minCellSize", "cellGap", "cellRadius", "emptyColor", "colors", "minValue", "maxValue", "weekStartsOn", "showMonthLabels", "showWeekdayLabels", "showLegend", "animateOnRender", "animationDuration", "animationStagger", "showExportButton", "exportFileName", "exportFormats", "exportScale", "exportBackgroundColor", "showTooltips", "ariaLabel", "valueFormatter", "monthLabelFormatter", "weekdayLabelFormatter", "tooltipFormatter", "onCellClick", "className"]);
30
30
  const descriptionId = useId();
31
31
  const theme = useTheme();
32
32
  const containerRef = useRef(null);
33
+ const chartSizeRef = useRef(null);
33
34
  const svgRef = useRef(null);
34
35
  const [activeCellKey, setActiveCellKey] = useState(null);
35
36
  const [activeTooltip, setActiveTooltip] = useState(null);
@@ -73,12 +74,12 @@ const HeatMapInner = (_a, ref) => {
73
74
  .map((datum) => datum.value)
74
75
  .filter((value) => Number.isFinite(value));
75
76
  const resolvedMaxValue = maxValue !== null && maxValue !== void 0 ? maxValue : Math.max(...values, minValue, 1);
76
- const safeCellSize = Math.max(cellSize, 1);
77
+ const preferredCellSize = Math.max(cellSize, 1);
78
+ const safeMinCellSize = Math.max(minCellSize, 1);
77
79
  const safeCellGap = Math.max(cellGap, 0);
78
80
  const safeCellRadius = Math.max(cellRadius, 0);
79
81
  const labelWidth = showWeekdayLabels ? 28 : 0;
80
82
  const monthLabelHeight = showMonthLabels ? 18 : 0;
81
- const step = safeCellSize + safeCellGap;
82
83
  const cells = useMemo(() => buildHeatMapCells({
83
84
  data,
84
85
  startDate: resolvedStartDate,
@@ -100,8 +101,28 @@ const HeatMapInner = (_a, ref) => {
100
101
  weekStartsOn,
101
102
  ]);
102
103
  const weekCount = cells.length > 0 ? Math.max(...cells.map((cell) => cell.weekIndex)) + 1 : 1;
103
- const width = labelWidth + weekCount * step - safeCellGap;
104
- const height = monthLabelHeight + 7 * step - safeCellGap;
104
+ const preferredStep = preferredCellSize + safeCellGap;
105
+ const preferredWidth = labelWidth + weekCount * preferredStep - safeCellGap;
106
+ const preferredHeight = monthLabelHeight + 7 * preferredStep - safeCellGap;
107
+ const chartSize = useChartResponsiveSize(chartSizeRef, {
108
+ width,
109
+ responsive,
110
+ defaultWidth: preferredWidth,
111
+ defaultHeight: preferredHeight,
112
+ minWidth: 1,
113
+ minHeight: 1,
114
+ });
115
+ const shouldFitWidth = responsive || width != null;
116
+ const targetCellSize = (chartSize.width - labelWidth + safeCellGap) / weekCount - safeCellGap;
117
+ const safeCellSize = shouldFitWidth
118
+ ? Math.max(targetCellSize, safeMinCellSize)
119
+ : preferredCellSize;
120
+ const step = safeCellSize + safeCellGap;
121
+ const chartWidth = labelWidth + weekCount * step - safeCellGap;
122
+ const chartHeight = monthLabelHeight + 7 * step - safeCellGap;
123
+ const chartWidthStyle = typeof width === "number" && Number.isFinite(width)
124
+ ? `${chartSize.width}px`
125
+ : chartSize.widthStyle;
105
126
  const formatValue = (cell) => { var _a; return (_a = valueFormatter === null || valueFormatter === void 0 ? void 0 : valueFormatter(cell.value, cell.datum)) !== null && _a !== void 0 ? _a : formatDefaultValue(cell.value); };
106
127
  const getCellFill = (cell) => {
107
128
  if (!cell.datum)
@@ -172,7 +193,7 @@ const HeatMapInner = (_a, ref) => {
172
193
  const elapsed = animationElapsed - index * safeAnimationStagger;
173
194
  return easeOutCubic(clamp(elapsed / safeAnimationDuration, 0, 1));
174
195
  };
175
- return (_jsxs(StyledContainer, Object.assign({ ref: containerRef, className: className }, props, { children: [_jsx(StyledChartScroller, { children: _jsxs(StyledChartFrame, { children: [showExportButton && exportFormats.length > 0 && (_jsx(StyledChartActions, { "data-chart-export-ignore": "true", children: _jsx(ChartExportControl, { rootRef: containerRef, svgRef: svgRef, fileName: exportFileName, formats: exportFormats, scale: exportScale, backgroundColor: resolvedExportBackgroundColor }) })), _jsxs(StyledSvg, { ref: svgRef, width: width, height: height, viewBox: `0 0 ${width} ${height}`, role: "img", "aria-label": ariaLabel, "aria-describedby": descriptionId, children: [_jsx("desc", { id: descriptionId, children: description }), showMonthLabels &&
196
+ return (_jsxs(StyledContainer, Object.assign({ ref: containerRef, className: className, "$fillAvailableWidth": chartSize.fillAvailableWidth }, props, { children: [_jsx(StyledChartScroller, { ref: chartSizeRef, "$width": chartWidthStyle, children: _jsxs(StyledChartFrame, { children: [showExportButton && exportFormats.length > 0 && (_jsx(StyledChartActions, { "data-chart-export-ignore": "true", children: _jsx(ChartExportControl, { rootRef: containerRef, svgRef: svgRef, fileName: exportFileName, formats: exportFormats, scale: exportScale, backgroundColor: resolvedExportBackgroundColor }) })), _jsxs(StyledSvg, { ref: svgRef, width: chartWidth, height: chartHeight, viewBox: `0 0 ${chartWidth} ${chartHeight}`, role: "img", "aria-label": ariaLabel, "aria-describedby": descriptionId, children: [_jsx("desc", { id: descriptionId, children: description }), showMonthLabels &&
176
197
  monthLabels.map((monthLabel) => (_jsx(StyledMonthLabel, { x: labelWidth + monthLabel.weekIndex * step, y: 10, children: monthLabel.label }, `${monthLabel.label}-${monthLabel.weekIndex}`))), showWeekdayLabels &&
177
198
  Array.from({ length: 7 }, (_, dayIndex) => {
178
199
  var _a;
@@ -1,6 +1,10 @@
1
1
  import { StyledChartActions } from "../ChartPrimitives";
2
- export declare const StyledContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
3
- export declare const StyledChartScroller: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
2
+ export declare const StyledContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
3
+ $fillAvailableWidth: boolean;
4
+ }>> & string;
5
+ export declare const StyledChartScroller: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
6
+ $width?: string;
7
+ }>> & string;
4
8
  export declare const StyledChartFrame: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
5
9
  export { StyledChartActions };
6
10
  export declare const StyledSvg: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").SVGProps<SVGSVGElement>, never>> & string;
@@ -9,16 +9,19 @@ export const StyledContainer = styled.div `
9
9
  display: inline-flex;
10
10
  flex-direction: column;
11
11
  gap: 10px;
12
+ width: ${({ $fillAvailableWidth }) => $fillAvailableWidth ? "100%" : "fit-content"};
12
13
  max-width: 100%;
13
14
  color: ${({ theme }) => theme.palette.text.primary};
14
15
  overflow: visible;
15
16
  `;
16
17
  export const StyledChartScroller = styled.div `
17
18
  display: flex;
19
+ width: ${({ $width }) => $width !== null && $width !== void 0 ? $width : "auto"};
18
20
  max-width: 100%;
19
21
  overflow-x: auto;
20
22
  overflow-y: visible;
21
23
  padding-bottom: 2px;
24
+ box-sizing: border-box;
22
25
  `;
23
26
  export const StyledChartFrame = styled.div `
24
27
  position: relative;
@@ -1,5 +1,5 @@
1
1
  import React, { HTMLAttributes } from "react";
2
- import type { ChartExportOptions } from "../ChartUtils";
2
+ import type { ChartDimension, ChartExportOptions } from "../ChartUtils";
3
3
  export type HeatMapDatum<TData = unknown> = {
4
4
  /** Date represented by this cell. ISO yyyy-mm-dd strings are recommended. */
5
5
  date: Date | string;
@@ -31,12 +31,18 @@ export type HeatMapTooltipState = {
31
31
  export type HeatMapProps<TData = unknown> = HTMLAttributes<HTMLDivElement> & ChartExportOptions & {
32
32
  /** Values rendered by the heatmap. Missing dates render as empty cells. */
33
33
  data: HeatMapDatum<TData>[];
34
+ /** Target heatmap width in pixels or any CSS length measured from the chart frame. */
35
+ width?: ChartDimension;
36
+ /** Measures the chart frame and resizes cells to fit the available width. Defaults to false. */
37
+ responsive?: boolean;
34
38
  /** First date to render. Defaults to the earliest date in data. */
35
39
  startDate?: Date | string;
36
40
  /** Last date to render. Defaults to the latest date in data. */
37
41
  endDate?: Date | string;
38
42
  /** Size of each square cell in pixels. Defaults to 12. */
39
43
  cellSize?: number;
44
+ /** Minimum rendered cell size in pixels when responsive sizing is active. Defaults to 6. */
45
+ minCellSize?: number;
40
46
  /** Gap between cells in pixels. Defaults to 4. */
41
47
  cellGap?: number;
42
48
  /** Cell corner radius in pixels. Defaults to 2. */
@@ -23,16 +23,17 @@ import { scaleLinear, scalePoint, scaleTime } from "d3-scale";
23
23
  import { forwardRef, useCallback, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState, } from "react";
24
24
  import { useTheme } from "styled-components";
25
25
  import { ChartExportControl } from "../ChartPrimitives";
26
- import { DEFAULT_CHART_EXPORT_FORMATS, copyChartImage, downloadChartImage, } from "../ChartUtils";
26
+ import { DEFAULT_CHART_EXPORT_FORMATS, copyChartImage, downloadChartImage, useChartResponsiveSize, } from "../ChartUtils";
27
27
  import { buildAreaPath, buildLinePath, clamp, easeOutCubic, formatDefaultValue, getGradientStops, getPointKey, getSeriesKey, getSeriesLabelText, getValueDomain, measureSvgPath, mergeChartMargin, normalizeTickValue, parseLineChartXValue, resolveXAxisType, useThemeColor, useThemeColors, } from "./LineChart.lib";
28
28
  import { StyledArea, StyledAxisLine, StyledAxisText, StyledChartActions, StyledChartFrame, StyledChartScroller, StyledContainer, StyledEmptyState, StyledGridLine, StyledHoverTarget, StyledLegend, StyledLegendItem, StyledLegendLabel, StyledLegendLine, StyledLegendValue, StyledLine, StyledPoint, StyledSvg, StyledTooltip, StyledTooltipHeader, StyledTooltipLabel, StyledTooltipMeta, StyledTooltipSwatch, StyledValueLabel, } from "./LineChart.styled";
29
29
  const LineChartInner = (_a, ref) => {
30
30
  var _b, _c, _d;
31
- var { data, series, seriesLabel = "Series", width = 720, height = 320, margin, xAxisType = "auto", curve = "monotone", lineColor, colors, colorGradient, lineWidth = 2.5, lineOpacity = 1, lineDasharray, showArea = false, areaColor, areaOpacity = 0.14, showPoints = false, pointRadius = 3, activePointRadius = 4, pointColor, pointBorderColor, pointBorderWidth = 1.5, pointOpacity = 1, yMin, yMax, xTickCount = 6, yTickCount = 5, showGridLines = true, showAxisLines = true, showXAxisLabels = true, showYAxisLabels = true, showLegend = false, showLabels = false, emptyLabel = "No data", ariaLabel = "Line chart", animateOnRender = false, animationDuration = 720, showExportButton = false, exportFileName = "line-chart", exportFormats = DEFAULT_CHART_EXPORT_FORMATS, exportScale = 2, exportBackgroundColor, showTooltips = false, valueFormatter, xValueFormatter, xTickFormatter, yTickFormatter, labelFormatter, tooltipFormatter, onPointClick, className } = _a, props = __rest(_a, ["data", "series", "seriesLabel", "width", "height", "margin", "xAxisType", "curve", "lineColor", "colors", "colorGradient", "lineWidth", "lineOpacity", "lineDasharray", "showArea", "areaColor", "areaOpacity", "showPoints", "pointRadius", "activePointRadius", "pointColor", "pointBorderColor", "pointBorderWidth", "pointOpacity", "yMin", "yMax", "xTickCount", "yTickCount", "showGridLines", "showAxisLines", "showXAxisLabels", "showYAxisLabels", "showLegend", "showLabels", "emptyLabel", "ariaLabel", "animateOnRender", "animationDuration", "showExportButton", "exportFileName", "exportFormats", "exportScale", "exportBackgroundColor", "showTooltips", "valueFormatter", "xValueFormatter", "xTickFormatter", "yTickFormatter", "labelFormatter", "tooltipFormatter", "onPointClick", "className"]);
31
+ var { data, series, seriesLabel = "Series", width, height, responsive = false, aspectRatio, minWidth = 240, minHeight = 200, margin, xAxisType = "auto", curve = "monotone", lineColor, colors, colorGradient, lineWidth = 2.5, lineOpacity = 1, lineDasharray, showArea = false, areaColor, areaOpacity = 0.14, showPoints = false, pointRadius = 3, activePointRadius = 4, pointColor, pointBorderColor, pointBorderWidth = 1.5, pointOpacity = 1, yMin, yMax, xTickCount = 6, yTickCount = 5, showGridLines = true, showAxisLines = true, showXAxisLabels = true, showYAxisLabels = true, showLegend = false, showLabels = false, emptyLabel = "No data", ariaLabel = "Line chart", animateOnRender = false, animationDuration = 720, showExportButton = false, exportFileName = "line-chart", exportFormats = DEFAULT_CHART_EXPORT_FORMATS, exportScale = 2, exportBackgroundColor, showTooltips = false, valueFormatter, xValueFormatter, xTickFormatter, yTickFormatter, labelFormatter, tooltipFormatter, onPointClick, className } = _a, props = __rest(_a, ["data", "series", "seriesLabel", "width", "height", "responsive", "aspectRatio", "minWidth", "minHeight", "margin", "xAxisType", "curve", "lineColor", "colors", "colorGradient", "lineWidth", "lineOpacity", "lineDasharray", "showArea", "areaColor", "areaOpacity", "showPoints", "pointRadius", "activePointRadius", "pointColor", "pointBorderColor", "pointBorderWidth", "pointOpacity", "yMin", "yMax", "xTickCount", "yTickCount", "showGridLines", "showAxisLines", "showXAxisLabels", "showYAxisLabels", "showLegend", "showLabels", "emptyLabel", "ariaLabel", "animateOnRender", "animationDuration", "showExportButton", "exportFileName", "exportFormats", "exportScale", "exportBackgroundColor", "showTooltips", "valueFormatter", "xValueFormatter", "xTickFormatter", "yTickFormatter", "labelFormatter", "tooltipFormatter", "onPointClick", "className"]);
32
32
  const descriptionId = useId();
33
33
  const gradientBaseId = useId();
34
34
  const theme = useTheme();
35
35
  const containerRef = useRef(null);
36
+ const chartSizeRef = useRef(null);
36
37
  const chartFrameRef = useRef(null);
37
38
  const svgRef = useRef(null);
38
39
  const tooltipRef = useRef(null);
@@ -46,8 +47,18 @@ const LineChartInner = (_a, ref) => {
46
47
  const themeLineColor = useThemeColor(lineColor);
47
48
  const themeColors = useThemeColors(colors);
48
49
  const resolvedMargin = mergeChartMargin(margin, showXAxisLabels, showYAxisLabels, showLabels);
49
- const safeWidth = Math.max(width, 240);
50
- const safeHeight = Math.max(height, 200);
50
+ const chartSize = useChartResponsiveSize(chartSizeRef, {
51
+ width,
52
+ height,
53
+ responsive,
54
+ aspectRatio,
55
+ defaultWidth: 720,
56
+ defaultHeight: 320,
57
+ minWidth: Math.max(minWidth, 1),
58
+ minHeight: Math.max(minHeight, 1),
59
+ });
60
+ const safeWidth = chartSize.width;
61
+ const safeHeight = chartSize.height;
51
62
  const plotWidth = Math.max(safeWidth - resolvedMargin.left - resolvedMargin.right, 1);
52
63
  const plotHeight = Math.max(safeHeight - resolvedMargin.top - resolvedMargin.bottom, 1);
53
64
  const resolvedGlobalLineWidth = Math.max(lineWidth, 1);
@@ -207,7 +218,7 @@ const LineChartInner = (_a, ref) => {
207
218
  if (resolvedXAxisType !== "time")
208
219
  return null;
209
220
  const timeValues = allPoints
210
- .map((point) => (point.parsedX instanceof Date ? point.parsedX.getTime() : null))
221
+ .map((point) => point.parsedX instanceof Date ? point.parsedX.getTime() : null)
211
222
  .filter((value) => value != null);
212
223
  const min = Math.min(...timeValues);
213
224
  const max = Math.max(...timeValues);
@@ -289,7 +300,8 @@ const LineChartInner = (_a, ref) => {
289
300
  }, [renderedSeries, renderedSeriesKey]);
290
301
  useLayoutEffect(() => {
291
302
  var _a;
292
- if (!animateOnRender || renderedSeries.every((seriesEntry) => !seriesEntry.linePath)) {
303
+ if (!animateOnRender ||
304
+ renderedSeries.every((seriesEntry) => !seriesEntry.linePath)) {
293
305
  setAnimationProgress(1);
294
306
  return;
295
307
  }
@@ -307,7 +319,9 @@ const LineChartInner = (_a, ref) => {
307
319
  if (startTime == null)
308
320
  startTime = timestamp;
309
321
  const elapsed = timestamp - startTime;
310
- const progress = safeDuration === 0 ? 1 : easeOutCubic(clamp(elapsed / safeDuration, 0, 1));
322
+ const progress = safeDuration === 0
323
+ ? 1
324
+ : easeOutCubic(clamp(elapsed / safeDuration, 0, 1));
311
325
  setAnimationProgress(progress);
312
326
  if (progress < 1) {
313
327
  animationFrame = window.requestAnimationFrame(runAnimation);
@@ -337,7 +351,10 @@ const LineChartInner = (_a, ref) => {
337
351
  const yTicks = useMemo(() => Array.from(new Set(yScale
338
352
  .ticks(Math.max(yTickCount, 2))
339
353
  .map((tick) => normalizeTickValue(tick)))), [yScale, yTickCount]);
340
- const formatValue = (datum, sourceSeries) => { var _a; return (_a = valueFormatter === null || valueFormatter === void 0 ? void 0 : valueFormatter(datum.y, datum, sourceSeries)) !== null && _a !== void 0 ? _a : formatDefaultValue(datum.y); };
354
+ const formatValue = (datum, sourceSeries) => {
355
+ var _a;
356
+ return (_a = valueFormatter === null || valueFormatter === void 0 ? void 0 : valueFormatter(datum.y, datum, sourceSeries)) !== null && _a !== void 0 ? _a : formatDefaultValue(datum.y);
357
+ };
341
358
  const formatXValue = (datum, sourceSeries) => {
342
359
  var _a;
343
360
  return (_a = xValueFormatter === null || xValueFormatter === void 0 ? void 0 : xValueFormatter(datum.x, datum, sourceSeries)) !== null && _a !== void 0 ? _a : (datum.x instanceof Date ? datum.x.toLocaleDateString() : String(datum.x));
@@ -428,7 +445,7 @@ const LineChartInner = (_a, ref) => {
428
445
  .join(", ");
429
446
  const shouldAnimateStroke = animateOnRender && animationProgress < 1;
430
447
  const shouldShowDataLabels = showLabels && allPoints.length <= 24;
431
- return (_jsxs(StyledContainer, Object.assign({ ref: containerRef, className: className }, props, { children: [allPoints.length === 0 ? (_jsx(StyledEmptyState, { "$width": safeWidth, "$height": safeHeight, children: emptyLabel })) : (_jsx(StyledChartScroller, { children: _jsxs(StyledChartFrame, { ref: chartFrameRef, children: [showExportButton && exportFormats.length > 0 && (_jsx(StyledChartActions, { "data-chart-export-ignore": "true", children: _jsx(ChartExportControl, { rootRef: containerRef, svgRef: svgRef, fileName: exportFileName, formats: exportFormats, scale: exportScale, backgroundColor: resolvedExportBackgroundColor }) })), _jsxs(StyledSvg, { ref: svgRef, width: safeWidth, height: safeHeight, viewBox: `0 0 ${safeWidth} ${safeHeight}`, role: "img", "aria-label": ariaLabel, "aria-describedby": descriptionId, children: [_jsx("desc", { id: descriptionId, children: description }), _jsx("defs", { children: renderedSeries
448
+ return (_jsxs(StyledContainer, Object.assign({ ref: containerRef, className: className, "$fillAvailableWidth": chartSize.fillAvailableWidth }, props, { children: [_jsx(StyledChartScroller, { ref: chartSizeRef, "$width": chartSize.widthStyle, "$height": chartSize.heightStyle, children: allPoints.length === 0 ? (_jsx(StyledEmptyState, { "$width": safeWidth, "$height": safeHeight, children: emptyLabel })) : (_jsxs(StyledChartFrame, { ref: chartFrameRef, children: [showExportButton && exportFormats.length > 0 && (_jsx(StyledChartActions, { "data-chart-export-ignore": "true", children: _jsx(ChartExportControl, { rootRef: containerRef, svgRef: svgRef, fileName: exportFileName, formats: exportFormats, scale: exportScale, backgroundColor: resolvedExportBackgroundColor }) })), _jsxs(StyledSvg, { ref: svgRef, width: safeWidth, height: safeHeight, viewBox: `0 0 ${safeWidth} ${safeHeight}`, role: "img", "aria-label": ariaLabel, "aria-describedby": descriptionId, children: [_jsx("desc", { id: descriptionId, children: description }), _jsx("defs", { children: renderedSeries
432
449
  .filter((seriesEntry) => { var _a; return (_a = seriesEntry.gradientStops) === null || _a === void 0 ? void 0 : _a.length; })
433
450
  .map((seriesEntry) => {
434
451
  var _a;
@@ -437,7 +454,8 @@ const LineChartInner = (_a, ref) => {
437
454
  return (_jsx("stop", { offset: `${((_a = seriesEntry.gradientStops) !== null && _a !== void 0 ? _a : []).length === 1
438
455
  ? 100
439
456
  : (index /
440
- (((_b = seriesEntry.gradientStops) !== null && _b !== void 0 ? _b : []).length - 1)) *
457
+ (((_b = seriesEntry.gradientStops) !== null && _b !== void 0 ? _b : []).length -
458
+ 1)) *
441
459
  100}%`, stopColor: stop }, `${stop}-${index}`));
442
460
  }) }, seriesEntry.gradientId));
443
461
  }) }), showGridLines &&
@@ -446,10 +464,10 @@ const LineChartInner = (_a, ref) => {
446
464
  xTicks.map((tick, index) => {
447
465
  var _a, _b, _c;
448
466
  const x = resolvedXAxisType === "time"
449
- ? (_a = timeScale === null || timeScale === void 0 ? void 0 : timeScale(tick)) !== null && _a !== void 0 ? _a : 0
467
+ ? ((_a = timeScale === null || timeScale === void 0 ? void 0 : timeScale(tick)) !== null && _a !== void 0 ? _a : 0)
450
468
  : resolvedXAxisType === "linear"
451
- ? (_b = linearScale === null || linearScale === void 0 ? void 0 : linearScale(tick)) !== null && _b !== void 0 ? _b : 0
452
- : (_c = pointScale === null || pointScale === void 0 ? void 0 : pointScale(String(tick))) !== null && _c !== void 0 ? _c : 0;
469
+ ? ((_b = linearScale === null || linearScale === void 0 ? void 0 : linearScale(tick)) !== null && _b !== void 0 ? _b : 0)
470
+ : ((_c = pointScale === null || pointScale === void 0 ? void 0 : pointScale(String(tick))) !== null && _c !== void 0 ? _c : 0);
453
471
  return (_jsx(StyledAxisText, { x: resolvedMargin.left + x, y: resolvedMargin.top + plotHeight + 20, textAnchor: "middle", children: formatXTick(tick) }, `tick-x-${index}`));
454
472
  }), _jsxs("g", { transform: `translate(${resolvedMargin.left}, ${resolvedMargin.top})`, children: [_jsx(StyledHoverTarget, { x: 0, y: 0, width: plotWidth, height: plotHeight, onMouseEnter: (event) => {
455
473
  if (!showTooltips && !showPoints && !onPointClick)
@@ -488,7 +506,8 @@ const LineChartInner = (_a, ref) => {
488
506
  : undefined,
489
507
  opacity: isSeriesDimmed ? 0.7 : 1,
490
508
  } })), seriesEntry.linePath && (_jsx(StyledLine, { "$active": isSeriesActive, "$dimmed": isSeriesDimmed, ref: (node) => {
491
- linePathRefs.current[String(seriesEntry.key)] = node;
509
+ linePathRefs.current[String(seriesEntry.key)] =
510
+ node;
492
511
  }, d: seriesEntry.linePath, stroke: gradientReference, strokeWidth: isSeriesActive
493
512
  ? seriesEntry.lineWidth + 0.8
494
513
  : seriesEntry.lineWidth, strokeOpacity: seriesEntry.lineOpacity, strokeDasharray: shouldAnimateStroke && lineLength > 0
@@ -518,7 +537,7 @@ const LineChartInner = (_a, ref) => {
518
537
  renderedSeries.map((seriesEntry) => seriesEntry.points.map((point) => {
519
538
  var _a;
520
539
  return (_jsx(StyledValueLabel, { x: getPointX(point), y: getPointY(point) - 10, textAnchor: "middle", children: (_a = labelFormatter === null || labelFormatter === void 0 ? void 0 : labelFormatter(point, point.index, seriesEntry.sourceSeries)) !== null && _a !== void 0 ? _a : formatValue(point, seriesEntry.sourceSeries) }, `label-${point.key}`));
521
- }))] })] })] }) })), activeTooltip && activePoint && activeSeries && tooltipStyle && (_jsx(StyledTooltip, { ref: tooltipRef, style: tooltipStyle, children: tooltipFormatter ? (tooltipFormatter(activePoint, activePoint.index, activeSeries.sourceSeries)) : (_jsxs(_Fragment, { children: [_jsxs(StyledTooltipHeader, { children: [_jsx(StyledTooltipSwatch, { "$color": (_d = activePoint.color) !== null && _d !== void 0 ? _d : activeSeries.pointColor }), _jsx(StyledTooltipLabel, { children: formatXValue(activePoint, activeSeries.sourceSeries) })] }), _jsxs(StyledTooltipMeta, { children: [_jsx("span", { children: activePoint.seriesLabel }), _jsx("span", { children: formatValue(activePoint, activeSeries.sourceSeries) })] })] })) })), showLegend && (_jsx(StyledLegend, { children: renderedSeries.map((seriesEntry) => {
540
+ }))] })] })] })) }), activeTooltip && activePoint && activeSeries && tooltipStyle && (_jsx(StyledTooltip, { ref: tooltipRef, style: tooltipStyle, children: tooltipFormatter ? (tooltipFormatter(activePoint, activePoint.index, activeSeries.sourceSeries)) : (_jsxs(_Fragment, { children: [_jsxs(StyledTooltipHeader, { children: [_jsx(StyledTooltipSwatch, { "$color": (_d = activePoint.color) !== null && _d !== void 0 ? _d : activeSeries.pointColor }), _jsx(StyledTooltipLabel, { children: formatXValue(activePoint, activeSeries.sourceSeries) })] }), _jsxs(StyledTooltipMeta, { children: [_jsx("span", { children: activePoint.seriesLabel }), _jsx("span", { children: formatValue(activePoint, activeSeries.sourceSeries) })] })] })) })), showLegend && (_jsx(StyledLegend, { children: renderedSeries.map((seriesEntry) => {
522
541
  const latestPoint = seriesEntry.points[seriesEntry.points.length - 1];
523
542
  if (!latestPoint)
524
543
  return null;
@@ -1,6 +1,11 @@
1
1
  import { StyledChartActions } from "../ChartPrimitives";
2
- export declare const StyledContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
3
- export declare const StyledChartScroller: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
2
+ export declare const StyledContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
3
+ $fillAvailableWidth: boolean;
4
+ }>> & string;
5
+ export declare const StyledChartScroller: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
6
+ $width?: string;
7
+ $height?: string;
8
+ }>> & string;
4
9
  export declare const StyledChartFrame: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
5
10
  export { StyledChartActions };
6
11
  export declare const StyledSvg: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").SVGProps<SVGSVGElement>, never>> & string;
@@ -10,7 +10,7 @@ export const StyledContainer = styled.div `
10
10
  align-items: flex-start;
11
11
  flex-wrap: wrap;
12
12
  gap: 20px;
13
- width: fit-content;
13
+ width: ${({ $fillAvailableWidth }) => $fillAvailableWidth ? "100%" : "fit-content"};
14
14
  max-width: 100%;
15
15
  color: ${({ theme }) => theme.palette.text.primary};
16
16
  box-sizing: border-box;
@@ -18,10 +18,13 @@ export const StyledContainer = styled.div `
18
18
  `;
19
19
  export const StyledChartScroller = styled.div `
20
20
  display: flex;
21
+ width: ${({ $width }) => $width !== null && $width !== void 0 ? $width : "auto"};
22
+ height: ${({ $height }) => $height !== null && $height !== void 0 ? $height : "auto"};
21
23
  max-width: 100%;
22
24
  overflow-x: auto;
23
25
  overflow-y: visible;
24
26
  padding-bottom: 2px;
27
+ box-sizing: border-box;
25
28
  `;
26
29
  export const StyledChartFrame = styled.div `
27
30
  position: relative;
@@ -120,6 +123,7 @@ export const StyledEmptyState = styled.div `
120
123
  justify-content: center;
121
124
  width: ${({ $width }) => $width}px;
122
125
  height: ${({ $height }) => $height}px;
126
+ box-sizing: border-box;
123
127
  border: 1px dashed ${({ theme }) => theme.palette.divider};
124
128
  border-radius: 8px;
125
129
  background: linear-gradient(
@@ -1,5 +1,5 @@
1
1
  import React, { HTMLAttributes } from "react";
2
- import type { ChartExportOptions } from "../ChartUtils";
2
+ import type { ChartDimension, ChartExportOptions } from "../ChartUtils";
3
3
  export type LineChartDatum<TData = unknown> = {
4
4
  /** Stable identifier for the point. Falls back to x and index when omitted. */
5
5
  id?: string | number;
@@ -104,10 +104,18 @@ export type LineChartProps<TData = unknown> = HTMLAttributes<HTMLDivElement> & C
104
104
  series?: LineChartSeries<TData>[];
105
105
  /** Label used for the single-line variant in legend and tooltip context. */
106
106
  seriesLabel?: React.ReactNode;
107
- /** SVG width in pixels. Defaults to 720. */
108
- width?: number;
109
- /** SVG height in pixels. Defaults to 320. */
110
- height?: number;
107
+ /** SVG width in pixels or any CSS length measured from the chart frame. Defaults to 720. */
108
+ width?: ChartDimension;
109
+ /** SVG height in pixels or any CSS length measured from the chart frame. Defaults to 320. */
110
+ height?: ChartDimension;
111
+ /** Measures the chart frame and fits the SVG width to its available space. Defaults to false. */
112
+ responsive?: boolean;
113
+ /** Calculates height from resolved width when height is omitted. */
114
+ aspectRatio?: number;
115
+ /** Minimum rendered SVG width in pixels. Defaults to 240. */
116
+ minWidth?: number;
117
+ /** Minimum rendered SVG height in pixels. Defaults to 200. */
118
+ minHeight?: number;
111
119
  /** Partial chart margin overrides. Defaults are based on visible labels. */
112
120
  margin?: Partial<LineChartMargin>;
113
121
  /** X-axis scale type. Defaults to "auto". */
@@ -23,15 +23,16 @@ import { forwardRef, useEffect, useId, useImperativeHandle, useMemo, useRef, use
23
23
  import { arc, pie } from "d3-shape";
24
24
  import { useTheme } from "styled-components";
25
25
  import { ChartExportControl } from "../ChartPrimitives";
26
- import { DEFAULT_CHART_EXPORT_FORMATS, copyChartImage, downloadChartImage, } from "../ChartUtils";
26
+ import { DEFAULT_CHART_EXPORT_FORMATS, copyChartImage, downloadChartImage, useChartResponsiveSize, } from "../ChartUtils";
27
27
  import { clamp, easeOutCubic, formatDefaultValue, getGradientColor, getSliceKey, useThemeColors, } from "./PieChart.lib";
28
28
  import { StyledCenter, StyledCenterLabel, StyledCenterPanel, StyledCenterValue, StyledChartActions, StyledChartWrap, StyledContainer, StyledEmptyState, StyledLabel, StyledLegend, StyledLegendItem, StyledLegendLabel, StyledLegendMeta, StyledLegendPercent, StyledLegendValue, StyledSlice, StyledSvg, StyledSwatch, StyledTooltip, StyledTooltipHeader, StyledTooltipLabel, StyledTooltipMeta, StyledTooltipSwatch, } from "./PieChart.styled";
29
29
  const PieChartInner = (_a, ref) => {
30
30
  var _b, _c;
31
- var { data, size = 220, innerRadius = 58, outerRadius, cornerRadius = 1, padAngle = 0.004, colors, colorGradient, sliceOpacity = 1, sliceBorderColor, sliceBorderWidth = 1, sliceBorderOpacity = 1, sliceBorderLineJoin = "round", showLegend = true, showLegendSwatches = true, showLegendLabels = true, showLegendValues = true, showLegendPercentages = true, showLabels = false, centerLabel, centerValue, emptyLabel = "No data", ariaLabel = "Pie chart", animateOnRender = false, animationDuration = 520, animationStagger = 35, showExportButton = false, exportFileName = "pie-chart", exportFormats = DEFAULT_CHART_EXPORT_FORMATS, exportScale = 2, exportBackgroundColor, showTooltips = false, valueFormatter, labelFormatter, tooltipFormatter, onSliceClick, onLegendItemClick, className } = _a, props = __rest(_a, ["data", "size", "innerRadius", "outerRadius", "cornerRadius", "padAngle", "colors", "colorGradient", "sliceOpacity", "sliceBorderColor", "sliceBorderWidth", "sliceBorderOpacity", "sliceBorderLineJoin", "showLegend", "showLegendSwatches", "showLegendLabels", "showLegendValues", "showLegendPercentages", "showLabels", "centerLabel", "centerValue", "emptyLabel", "ariaLabel", "animateOnRender", "animationDuration", "animationStagger", "showExportButton", "exportFileName", "exportFormats", "exportScale", "exportBackgroundColor", "showTooltips", "valueFormatter", "labelFormatter", "tooltipFormatter", "onSliceClick", "onLegendItemClick", "className"]);
31
+ var { data, size, responsive = false, minSize = 120, innerRadius, outerRadius, cornerRadius = 1, padAngle = 0.004, colors, colorGradient, sliceOpacity = 1, sliceBorderColor, sliceBorderWidth = 1, sliceBorderOpacity = 1, sliceBorderLineJoin = "round", showLegend = true, showLegendSwatches = true, showLegendLabels = true, showLegendValues = true, showLegendPercentages = true, showLabels = false, centerLabel, centerValue, emptyLabel = "No data", ariaLabel = "Pie chart", animateOnRender = false, animationDuration = 520, animationStagger = 35, showExportButton = false, exportFileName = "pie-chart", exportFormats = DEFAULT_CHART_EXPORT_FORMATS, exportScale = 2, exportBackgroundColor, showTooltips = false, valueFormatter, labelFormatter, tooltipFormatter, onSliceClick, onLegendItemClick, className } = _a, props = __rest(_a, ["data", "size", "responsive", "minSize", "innerRadius", "outerRadius", "cornerRadius", "padAngle", "colors", "colorGradient", "sliceOpacity", "sliceBorderColor", "sliceBorderWidth", "sliceBorderOpacity", "sliceBorderLineJoin", "showLegend", "showLegendSwatches", "showLegendLabels", "showLegendValues", "showLegendPercentages", "showLabels", "centerLabel", "centerValue", "emptyLabel", "ariaLabel", "animateOnRender", "animationDuration", "animationStagger", "showExportButton", "exportFileName", "exportFormats", "exportScale", "exportBackgroundColor", "showTooltips", "valueFormatter", "labelFormatter", "tooltipFormatter", "onSliceClick", "onLegendItemClick", "className"]);
32
32
  const descriptionId = useId();
33
33
  const theme = useTheme();
34
34
  const containerRef = useRef(null);
35
+ const chartSizeRef = useRef(null);
35
36
  const svgRef = useRef(null);
36
37
  const [activeSliceKey, setActiveSliceKey] = useState(null);
37
38
  const [activeTooltip, setActiveTooltip] = useState(null);
@@ -39,7 +40,21 @@ const PieChartInner = (_a, ref) => {
39
40
  const themeColors = useThemeColors(colors);
40
41
  const validData = useMemo(() => data.filter((datum) => Number.isFinite(datum.value) && datum.value > 0), [data]);
41
42
  const total = useMemo(() => validData.reduce((sum, datum) => sum + datum.value, 0), [validData]);
42
- const radius = outerRadius !== null && outerRadius !== void 0 ? outerRadius : Math.max(size / 2 - 6, 0);
43
+ const chartSize = useChartResponsiveSize(chartSizeRef, {
44
+ width: size,
45
+ responsive,
46
+ aspectRatio: 1,
47
+ defaultWidth: 220,
48
+ defaultHeight: 220,
49
+ minWidth: Math.max(minSize, 1),
50
+ minHeight: Math.max(minSize, 1),
51
+ });
52
+ const safeSize = Math.min(chartSize.width, chartSize.height);
53
+ const radius = outerRadius !== null && outerRadius !== void 0 ? outerRadius : Math.max(safeSize / 2 - 6, 0);
54
+ const shouldScaleDefaultInnerRadius = innerRadius == null && (responsive || typeof size === "string");
55
+ const defaultInnerRadius = shouldScaleDefaultInnerRadius
56
+ ? Math.max(radius * (58 / 104), 0)
57
+ : 58;
43
58
  const resolvedSliceOpacity = clamp(sliceOpacity, 0, 1);
44
59
  const resolvedSliceBorderWidth = Math.max(sliceBorderWidth, 0);
45
60
  const resolvedSliceBorderOpacity = clamp(sliceBorderOpacity, 0, 1);
@@ -69,7 +84,7 @@ const PieChartInner = (_a, ref) => {
69
84
  });
70
85
  }),
71
86
  }), [exportFileName, exportScale, resolvedExportBackgroundColor]);
72
- const resolvedInnerRadius = Math.min(innerRadius, radius - 1);
87
+ const resolvedInnerRadius = Math.max(Math.min(innerRadius !== null && innerRadius !== void 0 ? innerRadius : defaultInnerRadius, radius - 1), 0);
73
88
  const centerPanelDiameter = Math.max(resolvedInnerRadius * 1.62, 52);
74
89
  const labelRadius = resolvedInnerRadius > 0
75
90
  ? resolvedInnerRadius + (radius - resolvedInnerRadius) / 2
@@ -155,35 +170,35 @@ const PieChartInner = (_a, ref) => {
155
170
  const activeTooltipSlice = showTooltips && activeTooltip
156
171
  ? slices.find((slice, index) => getSliceKey(slice.data, index) === activeTooltip.sliceKey)
157
172
  : null;
158
- return (_jsxs(StyledContainer, Object.assign({ ref: containerRef, className: className }, props, { children: [slices.length === 0 ? (_jsx(StyledEmptyState, { "$size": size, children: emptyLabel })) : (_jsxs(StyledChartWrap, { children: [showExportButton && exportFormats.length > 0 && (_jsx(StyledChartActions, { "data-chart-export-ignore": "true", children: _jsx(ChartExportControl, { rootRef: containerRef, svgRef: svgRef, fileName: exportFileName, formats: exportFormats, scale: exportScale, backgroundColor: resolvedExportBackgroundColor }) })), _jsxs(StyledSvg, { ref: svgRef, width: size, height: size, viewBox: `0 0 ${size} ${size}`, role: "img", "aria-label": ariaLabel, "aria-describedby": descriptionId, children: [_jsx("desc", { id: descriptionId, children: slices
159
- .map((slice) => `${slice.data.label}: ${formatDefaultValue(slice.data.value)}`)
160
- .join(", ") }), _jsx("g", { transform: `translate(${size / 2}, ${size / 2})`, children: slices.map((slice, index) => {
161
- var _a;
162
- const sliceKey = getSliceKey(slice.data, index);
163
- const sliceAnimationProgress = getSliceAnimationProgress(index);
164
- const animatedSlice = Object.assign(Object.assign({}, slice), { startAngle: animationStartAngle +
165
- (slice.startAngle - animationStartAngle) *
166
- sliceAnimationProgress, endAngle: animationStartAngle +
167
- (slice.endAngle - animationStartAngle) *
168
- sliceAnimationProgress });
169
- const path = arcGenerator(animatedSlice);
170
- const labelPosition = labelArcGenerator.centroid(slice);
171
- const percent = Math.round(slice.percent * 100);
172
- return (_jsxs("g", { children: [_jsx(StyledSlice, { "$active": activeSliceKey === sliceKey, d: path !== null && path !== void 0 ? path : undefined, fill: slice.color, fillOpacity: resolvedSliceOpacity, stroke: resolvedSliceBorderColor, strokeWidth: resolvedSliceBorderWidth, strokeOpacity: resolvedSliceBorderOpacity, strokeLinejoin: sliceBorderLineJoin, tabIndex: 0, onFocus: () => setActiveSliceKey(sliceKey), onBlur: () => setActiveSliceKey(null), onMouseEnter: (event) => {
173
- setActiveSliceKey(sliceKey);
174
- updateTooltipPosition(event, sliceKey);
175
- }, onMouseMove: (event) => updateTooltipPosition(event, sliceKey), onMouseLeave: () => {
176
- setActiveSliceKey(null);
177
- setActiveTooltip(null);
178
- }, onClick: (event) => onSliceClick === null || onSliceClick === void 0 ? void 0 : onSliceClick(event, slice.data), onKeyDown: (event) => {
179
- if (event.key !== "Enter" && event.key !== " ")
180
- return;
181
- event.preventDefault();
182
- onSliceClick === null || onSliceClick === void 0 ? void 0 : onSliceClick(event, slice.data);
183
- }, "aria-label": `${slice.data.label}: ${formatDefaultValue(slice.data.value)}, ${percent}%` }), showLabels &&
184
- slice.percent >= 0.05 &&
185
- sliceAnimationProgress >= 0.92 && (_jsx(StyledLabel, { x: labelPosition[0], y: labelPosition[1], textAnchor: "middle", dominantBaseline: "central", children: (_a = labelFormatter === null || labelFormatter === void 0 ? void 0 : labelFormatter(slice.data, slice.percent)) !== null && _a !== void 0 ? _a : `${percent}%` }))] }, sliceKey));
186
- }) })] }), (centerLabel != null || centerValue != null) && (_jsx(StyledCenter, { children: _jsxs(StyledCenterPanel, { "$diameter": centerPanelDiameter, children: [centerValue != null && (_jsx(StyledCenterValue, { children: centerValue })), centerLabel != null && (_jsx(StyledCenterLabel, { children: centerLabel }))] }) }))] })), shouldShowLegend && (_jsx(StyledLegend, { children: slices.map((slice, index) => {
173
+ return (_jsxs(StyledContainer, Object.assign({ ref: containerRef, className: className, "$fillAvailableWidth": chartSize.fillAvailableWidth }, props, { children: [_jsx(StyledChartWrap, { ref: chartSizeRef, "$width": chartSize.widthStyle, "$height": chartSize.heightStyle, children: slices.length === 0 ? (_jsx(StyledEmptyState, { "$size": safeSize, children: emptyLabel })) : (_jsxs(_Fragment, { children: [showExportButton && exportFormats.length > 0 && (_jsx(StyledChartActions, { "data-chart-export-ignore": "true", children: _jsx(ChartExportControl, { rootRef: containerRef, svgRef: svgRef, fileName: exportFileName, formats: exportFormats, scale: exportScale, backgroundColor: resolvedExportBackgroundColor }) })), _jsxs(StyledSvg, { ref: svgRef, width: safeSize, height: safeSize, viewBox: `0 0 ${safeSize} ${safeSize}`, role: "img", "aria-label": ariaLabel, "aria-describedby": descriptionId, children: [_jsx("desc", { id: descriptionId, children: slices
174
+ .map((slice) => `${slice.data.label}: ${formatDefaultValue(slice.data.value)}`)
175
+ .join(", ") }), _jsx("g", { transform: `translate(${safeSize / 2}, ${safeSize / 2})`, children: slices.map((slice, index) => {
176
+ var _a;
177
+ const sliceKey = getSliceKey(slice.data, index);
178
+ const sliceAnimationProgress = getSliceAnimationProgress(index);
179
+ const animatedSlice = Object.assign(Object.assign({}, slice), { startAngle: animationStartAngle +
180
+ (slice.startAngle - animationStartAngle) *
181
+ sliceAnimationProgress, endAngle: animationStartAngle +
182
+ (slice.endAngle - animationStartAngle) *
183
+ sliceAnimationProgress });
184
+ const path = arcGenerator(animatedSlice);
185
+ const labelPosition = labelArcGenerator.centroid(slice);
186
+ const percent = Math.round(slice.percent * 100);
187
+ return (_jsxs("g", { children: [_jsx(StyledSlice, { "$active": activeSliceKey === sliceKey, d: path !== null && path !== void 0 ? path : undefined, fill: slice.color, fillOpacity: resolvedSliceOpacity, stroke: resolvedSliceBorderColor, strokeWidth: resolvedSliceBorderWidth, strokeOpacity: resolvedSliceBorderOpacity, strokeLinejoin: sliceBorderLineJoin, tabIndex: 0, onFocus: () => setActiveSliceKey(sliceKey), onBlur: () => setActiveSliceKey(null), onMouseEnter: (event) => {
188
+ setActiveSliceKey(sliceKey);
189
+ updateTooltipPosition(event, sliceKey);
190
+ }, onMouseMove: (event) => updateTooltipPosition(event, sliceKey), onMouseLeave: () => {
191
+ setActiveSliceKey(null);
192
+ setActiveTooltip(null);
193
+ }, onClick: (event) => onSliceClick === null || onSliceClick === void 0 ? void 0 : onSliceClick(event, slice.data), onKeyDown: (event) => {
194
+ if (event.key !== "Enter" && event.key !== " ")
195
+ return;
196
+ event.preventDefault();
197
+ onSliceClick === null || onSliceClick === void 0 ? void 0 : onSliceClick(event, slice.data);
198
+ }, "aria-label": `${slice.data.label}: ${formatDefaultValue(slice.data.value)}, ${percent}%` }), showLabels &&
199
+ slice.percent >= 0.05 &&
200
+ sliceAnimationProgress >= 0.92 && (_jsx(StyledLabel, { x: labelPosition[0], y: labelPosition[1], textAnchor: "middle", dominantBaseline: "central", children: (_a = labelFormatter === null || labelFormatter === void 0 ? void 0 : labelFormatter(slice.data, slice.percent)) !== null && _a !== void 0 ? _a : `${percent}%` }))] }, sliceKey));
201
+ }) })] }), (centerLabel != null || centerValue != null) && (_jsx(StyledCenter, { children: _jsxs(StyledCenterPanel, { "$diameter": centerPanelDiameter, children: [centerValue != null && (_jsx(StyledCenterValue, { children: centerValue })), centerLabel != null && (_jsx(StyledCenterLabel, { children: centerLabel }))] }) }))] })) }), shouldShowLegend && (_jsx(StyledLegend, { children: slices.map((slice, index) => {
187
202
  const sliceKey = getSliceKey(slice.data, index);
188
203
  return (_jsxs(StyledLegendItem, { "$active": activeSliceKey === sliceKey, "$showSwatch": showLegendSwatches, "$showLabel": showLegendLabels, "$showMeta": showLegendMeta, tabIndex: 0, onMouseEnter: () => setActiveSliceKey(sliceKey), onMouseLeave: () => setActiveSliceKey(null), onFocus: () => setActiveSliceKey(sliceKey), onBlur: () => setActiveSliceKey(null), onClick: (event) => onLegendItemClick === null || onLegendItemClick === void 0 ? void 0 : onLegendItemClick(event, slice.data), onKeyDown: (event) => {
189
204
  if (event.key !== "Enter" && event.key !== " ")