@monolith-forensics/monolith-ui 1.8.1-dev.0 → 1.8.1-dev.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 (61) hide show
  1. package/dist/SelectBox/SelectBox.js +2 -2
  2. package/dist/SelectBox/select-box.styled-components.d.ts +1 -0
  3. package/dist/SelectBox/select-box.styled-components.js +3 -2
  4. package/dist/SelectBox/types.d.ts +1 -0
  5. package/package.json +1 -1
  6. package/dist/BarChart/BarChart.d.ts +0 -3
  7. package/dist/BarChart/BarChart.js +0 -511
  8. package/dist/BarChart/BarChart.lib.d.ts +0 -31
  9. package/dist/BarChart/BarChart.lib.js +0 -136
  10. package/dist/BarChart/BarChart.styled.d.ts +0 -49
  11. package/dist/BarChart/BarChart.styled.js +0 -111
  12. package/dist/BarChart/BarChart.types.d.ts +0 -170
  13. package/dist/BarChart/BarChart.types.js +0 -1
  14. package/dist/BarChart/index.d.ts +0 -3
  15. package/dist/BarChart/index.js +0 -2
  16. package/dist/ChartPrimitives/chartLegend.styled.d.ts +0 -12
  17. package/dist/ChartPrimitives/chartLegend.styled.js +0 -52
  18. package/dist/ChartPrimitives/chartTooltip.styled.d.ts +0 -19
  19. package/dist/ChartPrimitives/chartTooltip.styled.js +0 -61
  20. package/dist/ChartPrimitives/index.d.ts +0 -2
  21. package/dist/ChartPrimitives/index.js +0 -2
  22. package/dist/ChartUtils/chartColors.d.ts +0 -8
  23. package/dist/ChartUtils/chartColors.js +0 -65
  24. package/dist/ChartUtils/chartMath.d.ts +0 -3
  25. package/dist/ChartUtils/chartMath.js +0 -3
  26. package/dist/ChartUtils/index.d.ts +0 -2
  27. package/dist/ChartUtils/index.js +0 -2
  28. package/dist/HeatMap/HeatMap.d.ts +0 -3
  29. package/dist/HeatMap/HeatMap.js +0 -174
  30. package/dist/HeatMap/HeatMap.lib.d.ts +0 -30
  31. package/dist/HeatMap/HeatMap.lib.js +0 -115
  32. package/dist/HeatMap/HeatMap.styled.d.ts +0 -34
  33. package/dist/HeatMap/HeatMap.styled.js +0 -83
  34. package/dist/HeatMap/HeatMap.types.d.ts +0 -79
  35. package/dist/HeatMap/HeatMap.types.js +0 -1
  36. package/dist/HeatMap/index.d.ts +0 -3
  37. package/dist/HeatMap/index.js +0 -2
  38. package/dist/LineChart/LineChart.d.ts +0 -3
  39. package/dist/LineChart/LineChart.js +0 -491
  40. package/dist/LineChart/LineChart.lib.d.ts +0 -24
  41. package/dist/LineChart/LineChart.lib.js +0 -132
  42. package/dist/LineChart/LineChart.styled.d.ts +0 -57
  43. package/dist/LineChart/LineChart.styled.js +0 -150
  44. package/dist/LineChart/LineChart.types.d.ts +0 -192
  45. package/dist/LineChart/LineChart.types.js +0 -1
  46. package/dist/LineChart/index.d.ts +0 -3
  47. package/dist/LineChart/index.js +0 -2
  48. package/dist/PieChart/PieChart.d.ts +0 -2
  49. package/dist/PieChart/PieChart.js +0 -161
  50. package/dist/PieChart/PieChart.lib.d.ts +0 -5
  51. package/dist/PieChart/PieChart.lib.js +0 -19
  52. package/dist/PieChart/PieChart.styled.d.ts +0 -49
  53. package/dist/PieChart/PieChart.styled.js +0 -161
  54. package/dist/PieChart/PieChart.types.d.ts +0 -99
  55. package/dist/PieChart/PieChart.types.js +0 -1
  56. package/dist/PieChart/index.d.ts +0 -2
  57. package/dist/PieChart/index.js +0 -1
  58. package/dist/SuperDatePicker/SuperDatePicker.d.ts +0 -74
  59. package/dist/SuperDatePicker/SuperDatePicker.js +0 -557
  60. package/dist/SuperDatePicker/index.d.ts +0 -2
  61. package/dist/SuperDatePicker/index.js +0 -2
@@ -10,7 +10,7 @@ import { StyledInputContainer, StyledInnerItemContainer, EmptyComponent, GroupTi
10
10
  // Re-export for backward compatibility
11
11
  export { StyledInputContainer };
12
12
  export const SelectBox = ({ className, data = [], placeholder = "Select...", arrow = true, onChange, onSearch, searchFn, onScroll, loading, defaultValue, value, size = "sm", variant = "outlined", width = "100%", allowCustomValue = false, searchable = false, clearable = false, label, description, required = false, error, openOnFocus = true, renderOption, actionComponent, focused, grouped, OptionTooltip, // Custom tooltip component for search menu items
13
- DropDownProps = {}, debounceTime = 175, sort = false, disabled = false,
13
+ DropDownProps = {}, debounceTime = 175, sort = false, disabled = false, dynamicOptionHeight,
14
14
  // Enhanced focus control props
15
15
  triggerFocus = false, triggerOpen = false, onFocused, onOpened, }) => {
16
16
  var _a, _b, _c, _d, _e, _f;
@@ -276,7 +276,7 @@ triggerFocus = false, triggerOpen = false, onFocused, onOpened, }) => {
276
276
  // ============================================================================
277
277
  // Render Helper Functions
278
278
  // ============================================================================
279
- const renderOptionItem = (item, index) => (_jsx(Tooltip, { content: OptionTooltip ? _jsx(OptionTooltip, { data: item.data }) : null, side: "left", children: _jsx(StyledItem, { className: "mfFloatingItem", onClick: (e) => handleItemClick(e, item), "data-selected": (_value === null || _value === void 0 ? void 0 : _value.value) === item.value, "data-disabled": item.disabled, size: size, children: (renderOption === null || renderOption === void 0 ? void 0 : renderOption(item)) || _jsx(_Fragment, { children: item === null || item === void 0 ? void 0 : item.label }) }, index) }, index));
279
+ const renderOptionItem = (item, index) => (_jsx(Tooltip, { content: OptionTooltip ? _jsx(OptionTooltip, { data: item.data }) : null, side: "left", children: _jsx(StyledItem, { className: "mfFloatingItem", onClick: (e) => handleItemClick(e, item), "data-selected": (_value === null || _value === void 0 ? void 0 : _value.value) === item.value, "data-disabled": item.disabled, "$dynamicHeight": dynamicOptionHeight !== null && dynamicOptionHeight !== void 0 ? dynamicOptionHeight : Boolean(renderOption), size: size, children: (renderOption === null || renderOption === void 0 ? void 0 : renderOption(item)) || _jsx(_Fragment, { children: item === null || item === void 0 ? void 0 : item.label }) }, index) }, index));
280
280
  const renderActionButton = () => {
281
281
  if (clearable && (_value || !!inputValue)) {
282
282
  return (_jsx(ClearButton, { size: size, className: "input-btn", onClick: handleClear, onMouseDown: (e) => {
@@ -16,6 +16,7 @@ export declare const GroupTitle: import("styled-components/dist/types").IStyledC
16
16
  export declare const ActionMenu: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
17
17
  export declare const StyledItem: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
18
18
  size: Size;
19
+ $dynamicHeight?: boolean;
19
20
  }>> & string;
20
21
  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;
21
22
  export {};
@@ -99,10 +99,11 @@ export const ActionMenu = styled.div ``;
99
99
  export const StyledItem = styled.div `
100
100
  color: ${(props) => props.theme.palette.text.primary};
101
101
  border-radius: 3px;
102
+ box-sizing: border-box;
102
103
  display: flex;
103
104
  align-items: center;
104
105
  min-height: ${({ size }) => `${getControlSizeTokens(size).menuRowHeight}px`};
105
- height: ${({ size }) => `${getControlSizeTokens(size).menuRowHeight}px`};
106
+ height: ${({ size, $dynamicHeight }) => $dynamicHeight ? "auto" : `${getControlSizeTokens(size).menuRowHeight}px`};
106
107
  position: relative;
107
108
  user-select: none;
108
109
  outline: none;
@@ -113,7 +114,7 @@ export const StyledItem = styled.div `
113
114
 
114
115
  font-size: ${({ size }) => `${getControlSizeTokens(size).fontSize}px`};
115
116
 
116
- padding: ${({ size }) => `0px ${getControlSizeTokens(size).menuItemPaddingX}px`};
117
+ padding: ${({ size, $dynamicHeight }) => `${$dynamicHeight ? 6 : 0}px ${getControlSizeTokens(size).menuItemPaddingX}px`};
117
118
 
118
119
  &:hover {
119
120
  background-color: ${(props) => props.theme.palette.action.hover};
@@ -34,6 +34,7 @@ export type SelectBoxProps = {
34
34
  debounceTime?: number;
35
35
  sort?: boolean;
36
36
  disabled?: boolean;
37
+ dynamicOptionHeight?: boolean;
37
38
  renderOption?: (item: Option | string) => React.ReactNode;
38
39
  OptionTooltip?: (props: {
39
40
  data: any;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monolith-forensics/monolith-ui",
3
- "version": "1.8.1-dev.0",
3
+ "version": "1.8.1-dev.1",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "author": "Matt Danner (Monolith Forensics LLC)",
@@ -1,3 +0,0 @@
1
- import { BarChartProps } from "./BarChart.types";
2
- export declare const BarChart: <TData>({ data, series, width, height, orientation, seriesLayout, margin, barGap, groupBarGap, maxBarThickness, barRadius, colors, colorGradient, barOpacity, barBorderColor, barBorderWidth, barBorderOpacity, minValue, maxValue, valueTickCount, showGridLines, showAxisLines, showCategoryAxisLabels, showValueAxisLabels, showLegend, showLegendSwatches, showLegendLabels, showLegendValues, showLabels, emptyLabel, ariaLabel, animateOnRender, animationDuration, animationStagger, showTooltips, valueFormatter, categoryLabelFormatter, tickFormatter, labelFormatter, tooltipFormatter, onBarClick, onLegendItemClick, onSeriesLegendItemClick, className, ...props }: BarChartProps<TData>) => import("react/jsx-runtime").JSX.Element;
3
- export default BarChart;
@@ -1,511 +0,0 @@
1
- var __rest = (this && this.__rest) || function (s, e) {
2
- var t = {};
3
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
- t[p] = s[p];
5
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
- t[p[i]] = s[p[i]];
9
- }
10
- return t;
11
- };
12
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
13
- import { scaleBand, scaleLinear } from "d3-scale";
14
- import { useEffect, useId, useMemo, useRef, useState } from "react";
15
- import { useTheme } from "styled-components";
16
- import { clamp, easeOutCubic, formatDefaultValue, getBandPadding, getBarKey, getCategoryKey, getGradientColor, getGradientColorFromStops, getGradientStops, getRoundedBarPath, getSeriesKey, getSeriesLabelText, getValueDomain, mergeChartMargin, normalizeTickValue, useThemeColors, } from "./BarChart.lib";
17
- import { StyledAxisLine, StyledAxisText, StyledBar, StyledChartFrame, StyledChartScroller, StyledContainer, StyledEmptyState, StyledGridLine, StyledLegend, StyledLegendItem, StyledLegendLabel, StyledLegendValue, StyledSvg, StyledSwatch, StyledTooltip, StyledTooltipHeader, StyledTooltipLabel, StyledTooltipList, StyledTooltipMeta, StyledTooltipRow, StyledTooltipSwatch, StyledTooltipValue, StyledValueLabel, } from "./BarChart.styled";
18
- export const BarChart = (_a) => {
19
- var _b, _c, _d;
20
- var { data, series, width = 640, height = 320, orientation = "vertical", seriesLayout = "grouped", margin, barGap = 10, groupBarGap, maxBarThickness, barRadius = 3, colors, colorGradient, barOpacity = 1, barBorderColor, barBorderWidth = 1, barBorderOpacity = 1, minValue, maxValue, valueTickCount = 5, showGridLines = true, showAxisLines = true, showCategoryAxisLabels = true, showValueAxisLabels = true, showLegend = false, showLegendSwatches = true, showLegendLabels = true, showLegendValues = true, showLabels = false, emptyLabel = "No data", ariaLabel = "Bar chart", animateOnRender = false, animationDuration = 520, animationStagger = 35, showTooltips = false, valueFormatter, categoryLabelFormatter, tickFormatter, labelFormatter, tooltipFormatter, onBarClick, onLegendItemClick, onSeriesLegendItemClick, className } = _a, props = __rest(_a, ["data", "series", "width", "height", "orientation", "seriesLayout", "margin", "barGap", "groupBarGap", "maxBarThickness", "barRadius", "colors", "colorGradient", "barOpacity", "barBorderColor", "barBorderWidth", "barBorderOpacity", "minValue", "maxValue", "valueTickCount", "showGridLines", "showAxisLines", "showCategoryAxisLabels", "showValueAxisLabels", "showLegend", "showLegendSwatches", "showLegendLabels", "showLegendValues", "showLabels", "emptyLabel", "ariaLabel", "animateOnRender", "animationDuration", "animationStagger", "showTooltips", "valueFormatter", "categoryLabelFormatter", "tickFormatter", "labelFormatter", "tooltipFormatter", "onBarClick", "onLegendItemClick", "onSeriesLegendItemClick", "className"]);
21
- const descriptionId = useId();
22
- const theme = useTheme();
23
- const containerRef = useRef(null);
24
- const chartFrameRef = useRef(null);
25
- const tooltipRef = useRef(null);
26
- const [activeBarKey, setActiveBarKey] = useState(null);
27
- const [activeSeriesKey, setActiveSeriesKey] = useState(null);
28
- const [activeTooltip, setActiveTooltip] = useState(null);
29
- const [tooltipSize, setTooltipSize] = useState({ width: 0, height: 0 });
30
- const [animationElapsed, setAnimationElapsed] = useState(animateOnRender ? 0 : Number.POSITIVE_INFINITY);
31
- const themeColors = useThemeColors(colors);
32
- const isMultiSeries = ((_b = series === null || series === void 0 ? void 0 : series.length) !== null && _b !== void 0 ? _b : 0) > 0;
33
- const normalizedInputSeries = useMemo(() => {
34
- if (series === null || series === void 0 ? void 0 : series.length) {
35
- return series.map((seriesItem, seriesIndex) => {
36
- const fallbackLabel = `Series ${seriesIndex + 1}`;
37
- return {
38
- key: getSeriesKey(seriesItem, seriesIndex),
39
- label: seriesItem.label,
40
- labelText: getSeriesLabelText(seriesItem.label, fallbackLabel),
41
- color: seriesItem.color,
42
- colorGradient: seriesItem.colorGradient,
43
- sourceSeries: seriesItem,
44
- data: seriesItem.data.filter((datum) => Number.isFinite(datum.value)),
45
- };
46
- });
47
- }
48
- return [
49
- {
50
- key: "series-0",
51
- label: "Series",
52
- labelText: "Series",
53
- color: undefined,
54
- colorGradient: undefined,
55
- sourceSeries: undefined,
56
- data: (data !== null && data !== void 0 ? data : []).filter((datum) => Number.isFinite(datum.value)),
57
- },
58
- ];
59
- }, [data, series]);
60
- const safeWidth = Math.max(width, 180);
61
- const safeHeight = Math.max(height, 180);
62
- const safeBarRadius = Math.max(barRadius, 0);
63
- const safeBarGap = Math.max(barGap, 0);
64
- const safeGroupBarGap = Math.max(groupBarGap !== null && groupBarGap !== void 0 ? groupBarGap : barGap, 0);
65
- const safeMaxBarThickness = maxBarThickness != null ? Math.max(maxBarThickness, 1) : undefined;
66
- const resolvedBarOpacity = clamp(barOpacity, 0, 1);
67
- const resolvedBarBorderWidth = Math.max(barBorderWidth, 0);
68
- const resolvedBarBorderOpacity = clamp(barBorderOpacity, 0, 1);
69
- const resolvedBarBorderColor = barBorderColor !== null && barBorderColor !== void 0 ? barBorderColor : theme.palette.divider;
70
- const resolvedMargin = mergeChartMargin(orientation, margin, showCategoryAxisLabels, showValueAxisLabels, showLabels);
71
- const plotWidth = Math.max(safeWidth - resolvedMargin.left - resolvedMargin.right, 1);
72
- const plotHeight = Math.max(safeHeight - resolvedMargin.top - resolvedMargin.bottom, 1);
73
- const resolvedChart = useMemo(() => {
74
- const categorySeedMap = new Map();
75
- normalizedInputSeries.forEach((seriesEntry) => {
76
- seriesEntry.data.forEach((datum) => {
77
- const categoryKey = getCategoryKey(datum);
78
- if (!categorySeedMap.has(categoryKey)) {
79
- categorySeedMap.set(categoryKey, {
80
- key: categoryKey,
81
- label: datum.label,
82
- representativeDatum: datum,
83
- index: categorySeedMap.size,
84
- });
85
- }
86
- });
87
- });
88
- const categorySeeds = Array.from(categorySeedMap.values());
89
- const resolvedSeries = normalizedInputSeries.map((seriesEntry, seriesIndex) => {
90
- var _a, _b, _c;
91
- const dataByCategory = new Map();
92
- seriesEntry.data.forEach((datum, datumIndex) => {
93
- dataByCategory.set(getCategoryKey(datum), {
94
- datum,
95
- index: datumIndex,
96
- });
97
- });
98
- const colorStops = getGradientStops(seriesEntry.colorGradient);
99
- const gradientPreviewColor = getGradientColorFromStops(colorStops, Math.max(Math.floor((seriesEntry.data.length - 1) / 2), 0), Math.max(seriesEntry.data.length, 1));
100
- return {
101
- key: seriesEntry.key,
102
- label: seriesEntry.label,
103
- labelText: seriesEntry.labelText,
104
- color: (_c = (_b = (_a = seriesEntry.color) !== null && _a !== void 0 ? _a : gradientPreviewColor) !== null && _b !== void 0 ? _b : getGradientColor(colorGradient, seriesIndex, normalizedInputSeries.length)) !== null && _c !== void 0 ? _c : themeColors[seriesIndex % themeColors.length],
105
- colorStops,
106
- index: seriesIndex,
107
- totalValue: seriesEntry.data.reduce((sum, datum) => sum + datum.value, 0),
108
- sourceSeries: seriesEntry.sourceSeries,
109
- dataByCategory,
110
- };
111
- });
112
- let renderIndex = 0;
113
- const allBars = [];
114
- const categories = categorySeeds.map((category) => {
115
- let positiveTotal = 0;
116
- let negativeTotal = 0;
117
- const categoryBars = [];
118
- resolvedSeries.forEach((seriesEntry) => {
119
- var _a, _b;
120
- const seriesDatum = seriesEntry.dataByCategory.get(category.key);
121
- if (!seriesDatum)
122
- return;
123
- const datum = seriesDatum.datum;
124
- let valueStart = 0;
125
- let valueEnd = datum.value;
126
- if (isMultiSeries && seriesLayout === "stacked") {
127
- if (datum.value >= 0) {
128
- valueStart = positiveTotal;
129
- positiveTotal += datum.value;
130
- valueEnd = positiveTotal;
131
- }
132
- else {
133
- valueStart = negativeTotal;
134
- negativeTotal += datum.value;
135
- valueEnd = negativeTotal;
136
- }
137
- }
138
- const barKey = `${String(seriesEntry.key)}-${String(getBarKey(datum, seriesDatum.index))}-${category.key}`;
139
- const color = (_b = (_a = datum.color) !== null && _a !== void 0 ? _a : getGradientColorFromStops(seriesEntry.colorStops, seriesDatum.index, Math.max(seriesEntry.dataByCategory.size, 1))) !== null && _b !== void 0 ? _b : seriesEntry.color;
140
- const resolvedBar = Object.assign(Object.assign({}, datum), { key: barKey, keyString: String(barKey), color, index: seriesDatum.index, renderIndex, seriesKey: seriesEntry.key, seriesIndex: seriesEntry.index, seriesLabel: seriesEntry.label, seriesLabelText: seriesEntry.labelText, categoryKey: category.key, categoryLabel: category.label, valueStart,
141
- valueEnd, sourceSeries: seriesEntry.sourceSeries });
142
- renderIndex += 1;
143
- categoryBars.push(resolvedBar);
144
- allBars.push(resolvedBar);
145
- });
146
- return {
147
- key: category.key,
148
- label: category.label,
149
- index: category.index,
150
- representativeDatum: category.representativeDatum,
151
- bars: categoryBars,
152
- positiveTotal,
153
- negativeTotal,
154
- };
155
- });
156
- return {
157
- bars: allBars,
158
- categories,
159
- series: resolvedSeries.map((_a) => {
160
- var { colorStops: _colorStops, dataByCategory: _dataByCategory } = _a, seriesEntry = __rest(_a, ["colorStops", "dataByCategory"]);
161
- return seriesEntry;
162
- }),
163
- };
164
- }, [
165
- colorGradient,
166
- isMultiSeries,
167
- normalizedInputSeries,
168
- seriesLayout,
169
- themeColors,
170
- ]);
171
- const bars = resolvedChart.bars;
172
- const categories = resolvedChart.categories;
173
- const resolvedSeries = resolvedChart.series;
174
- const { inner: categoryPaddingInner, outer: categoryPaddingOuter } = useMemo(() => getBandPadding(safeBarGap, orientation === "vertical" ? plotWidth : plotHeight, categories.length), [categories.length, orientation, plotHeight, plotWidth, safeBarGap]);
175
- const categoryScale = useMemo(() => scaleBand()
176
- .domain(categories.map((category) => category.key))
177
- .range(orientation === "vertical" ? [0, plotWidth] : [0, plotHeight])
178
- .paddingInner(categoryPaddingInner)
179
- .paddingOuter(categoryPaddingOuter), [
180
- categories,
181
- categoryPaddingInner,
182
- categoryPaddingOuter,
183
- orientation,
184
- plotHeight,
185
- plotWidth,
186
- ]);
187
- const groupScale = useMemo(() => {
188
- if (!isMultiSeries || seriesLayout !== "grouped")
189
- return null;
190
- const { inner, outer } = getBandPadding(safeGroupBarGap, categoryScale.bandwidth(), resolvedSeries.length);
191
- return scaleBand()
192
- .domain(resolvedSeries.map((seriesEntry) => String(seriesEntry.key)))
193
- .range([0, categoryScale.bandwidth()])
194
- .paddingInner(inner)
195
- .paddingOuter(outer);
196
- }, [
197
- categoryScale,
198
- isMultiSeries,
199
- resolvedSeries,
200
- safeGroupBarGap,
201
- seriesLayout,
202
- ]);
203
- const domainValues = useMemo(() => {
204
- if (isMultiSeries && seriesLayout === "stacked") {
205
- return categories.flatMap((category) => [
206
- category.negativeTotal,
207
- category.positiveTotal,
208
- ]);
209
- }
210
- return bars.map((bar) => bar.value);
211
- }, [bars, categories, isMultiSeries, seriesLayout]);
212
- const valueScale = useMemo(() => {
213
- const scale = scaleLinear()
214
- .domain(getValueDomain(domainValues, minValue, maxValue))
215
- .range(orientation === "vertical" ? [plotHeight, 0] : [0, plotWidth]);
216
- if (minValue == null || maxValue == null) {
217
- scale.nice(Math.max(valueTickCount, 2));
218
- }
219
- return scale;
220
- }, [
221
- domainValues,
222
- maxValue,
223
- minValue,
224
- orientation,
225
- plotHeight,
226
- plotWidth,
227
- valueTickCount,
228
- ]);
229
- const zeroPosition = valueScale(0);
230
- const tickValues = useMemo(() => Array.from(new Set(valueScale
231
- .ticks(Math.max(valueTickCount, 2))
232
- .map((tick) => normalizeTickValue(tick)))), [valueScale, valueTickCount]);
233
- const stackTerminalBarKeys = useMemo(() => {
234
- const nextKeys = new Set();
235
- if (!isMultiSeries || seriesLayout !== "stacked") {
236
- return nextKeys;
237
- }
238
- categories.forEach((category) => {
239
- const positiveBars = category.bars.filter((bar) => bar.value > 0);
240
- const negativeBars = category.bars.filter((bar) => bar.value < 0);
241
- const topBar = positiveBars[positiveBars.length - 1];
242
- const bottomBar = negativeBars[negativeBars.length - 1];
243
- if (topBar)
244
- nextKeys.add(String(topBar.key));
245
- if (bottomBar)
246
- nextKeys.add(String(bottomBar.key));
247
- });
248
- return nextKeys;
249
- }, [categories, isMultiSeries, seriesLayout]);
250
- const safeAnimationDuration = Math.max(animationDuration, 0);
251
- const safeAnimationStagger = Math.max(animationStagger, 0);
252
- const totalAnimationDuration = safeAnimationDuration +
253
- Math.max(bars.length - 1, 0) * safeAnimationStagger;
254
- useEffect(() => {
255
- var _a;
256
- if (!animateOnRender || bars.length === 0) {
257
- setAnimationElapsed(Number.POSITIVE_INFINITY);
258
- return;
259
- }
260
- const prefersReducedMotion = typeof window !== "undefined" &&
261
- ((_a = window.matchMedia) === null || _a === void 0 ? void 0 : _a.call(window, "(prefers-reduced-motion: reduce)").matches);
262
- if (prefersReducedMotion) {
263
- setAnimationElapsed(Number.POSITIVE_INFINITY);
264
- return;
265
- }
266
- let animationFrame = 0;
267
- let startTime = null;
268
- setAnimationElapsed(0);
269
- const runAnimation = (timestamp) => {
270
- if (startTime == null)
271
- startTime = timestamp;
272
- const elapsed = timestamp - startTime;
273
- setAnimationElapsed(elapsed);
274
- if (elapsed < totalAnimationDuration) {
275
- animationFrame = window.requestAnimationFrame(runAnimation);
276
- }
277
- };
278
- animationFrame = window.requestAnimationFrame(runAnimation);
279
- return () => {
280
- window.cancelAnimationFrame(animationFrame);
281
- };
282
- }, [
283
- animateOnRender,
284
- bars.length,
285
- safeAnimationDuration,
286
- safeAnimationStagger,
287
- totalAnimationDuration,
288
- ]);
289
- const getBarAnimationProgress = (index) => {
290
- if (!animateOnRender || safeAnimationDuration === 0)
291
- return 1;
292
- const elapsed = animationElapsed - index * safeAnimationStagger;
293
- return easeOutCubic(clamp(elapsed / safeAnimationDuration, 0, 1));
294
- };
295
- const formatValue = (datum, sourceSeries) => { var _a; return (_a = valueFormatter === null || valueFormatter === void 0 ? void 0 : valueFormatter(datum.value, datum, sourceSeries)) !== null && _a !== void 0 ? _a : formatDefaultValue(datum.value); };
296
- const formatCategoryLabel = (category) => {
297
- var _a, _b;
298
- return (_b = categoryLabelFormatter === null || categoryLabelFormatter === void 0 ? void 0 : categoryLabelFormatter(category.representativeDatum, category.index, (_a = category.bars[0]) === null || _a === void 0 ? void 0 : _a.sourceSeries)) !== null && _b !== void 0 ? _b : category.label;
299
- };
300
- const formatTick = (value) => { var _a; return (_a = tickFormatter === null || tickFormatter === void 0 ? void 0 : tickFormatter(value)) !== null && _a !== void 0 ? _a : formatDefaultValue(value); };
301
- const formatSeriesValue = (seriesEntry) => {
302
- var _a;
303
- const totalDatum = {
304
- label: seriesEntry.labelText,
305
- value: seriesEntry.totalValue,
306
- };
307
- return ((_a = valueFormatter === null || valueFormatter === void 0 ? void 0 : valueFormatter(seriesEntry.totalValue, totalDatum, seriesEntry.sourceSeries)) !== null && _a !== void 0 ? _a : formatDefaultValue(seriesEntry.totalValue));
308
- };
309
- const updateTooltipPosition = (event, barKey) => {
310
- if (!showTooltips || !containerRef.current)
311
- return;
312
- const containerRect = containerRef.current.getBoundingClientRect();
313
- setActiveTooltip({
314
- barKey,
315
- x: event.clientX - containerRect.left,
316
- y: event.clientY - containerRect.top,
317
- });
318
- };
319
- const activeTooltipBar = showTooltips && activeTooltip
320
- ? (_c = bars.find((bar) => bar.key === activeTooltip.barKey)) !== null && _c !== void 0 ? _c : null
321
- : null;
322
- const activeTooltipCategory = isMultiSeries && activeTooltipBar
323
- ? (_d = categories.find((category) => category.key === activeTooltipBar.categoryKey)) !== null && _d !== void 0 ? _d : null
324
- : null;
325
- const tooltipStyle = useMemo(() => {
326
- if (!activeTooltip ||
327
- !containerRef.current ||
328
- !chartFrameRef.current ||
329
- !activeTooltipBar) {
330
- return null;
331
- }
332
- const containerRect = containerRef.current.getBoundingClientRect();
333
- const chartFrameRect = chartFrameRef.current.getBoundingClientRect();
334
- const chartFrameLeft = chartFrameRect.left - containerRect.left;
335
- const chartFrameTop = chartFrameRect.top - containerRect.top;
336
- const minLeft = chartFrameLeft + 8;
337
- const maxLeft = chartFrameLeft + chartFrameRect.width - tooltipSize.width - 8;
338
- const minTop = chartFrameTop + 8;
339
- const maxTop = chartFrameTop + chartFrameRect.height - tooltipSize.height - 8;
340
- return {
341
- left: clamp(activeTooltip.x + 12, minLeft, Math.max(minLeft, maxLeft)),
342
- top: clamp(activeTooltip.y - tooltipSize.height / 2, minTop, Math.max(minTop, maxTop)),
343
- transform: "none",
344
- };
345
- }, [activeTooltip, activeTooltipBar, tooltipSize.height, tooltipSize.width]);
346
- const shouldShowLegend = showLegend &&
347
- (isMultiSeries ? resolvedSeries.length > 0 : bars.length > 0) &&
348
- (showLegendSwatches || showLegendLabels || showLegendValues);
349
- const description = useMemo(() => {
350
- if (isMultiSeries) {
351
- return categories
352
- .map((category) => {
353
- const seriesValues = category.bars
354
- .map((bar) => `${bar.seriesLabelText}: ${formatDefaultValue(bar.value)}`)
355
- .join(", ");
356
- return `${category.label}: ${seriesValues}`;
357
- })
358
- .join(". ");
359
- }
360
- return bars
361
- .map((bar) => `${bar.label}: ${formatDefaultValue(bar.value)}`)
362
- .join(", ");
363
- }, [bars, categories, isMultiSeries]);
364
- useEffect(() => {
365
- if (!tooltipRef.current ||
366
- !activeTooltipBar ||
367
- (isMultiSeries && !activeTooltipCategory)) {
368
- setTooltipSize({ width: 0, height: 0 });
369
- return;
370
- }
371
- setTooltipSize({
372
- width: tooltipRef.current.offsetWidth,
373
- height: tooltipRef.current.offsetHeight,
374
- });
375
- }, [activeTooltipBar, activeTooltipCategory, isMultiSeries]);
376
- return (_jsxs(StyledContainer, Object.assign({ ref: containerRef, className: className }, props, { children: [bars.length === 0 ? (_jsx(StyledEmptyState, { "$width": safeWidth, "$height": safeHeight, children: emptyLabel })) : (_jsx(StyledChartScroller, { children: _jsx(StyledChartFrame, { ref: chartFrameRef, children: _jsxs(StyledSvg, { width: safeWidth, height: safeHeight, viewBox: `0 0 ${safeWidth} ${safeHeight}`, role: "img", "aria-label": ariaLabel, "aria-describedby": descriptionId, children: [_jsx("desc", { id: descriptionId, children: description }), showGridLines &&
377
- tickValues.map((tick) => {
378
- const tickPosition = valueScale(tick);
379
- return orientation === "vertical" ? (_jsx(StyledGridLine, { x1: resolvedMargin.left, x2: resolvedMargin.left + plotWidth, y1: resolvedMargin.top + tickPosition, y2: resolvedMargin.top + tickPosition }, `grid-${tick}`)) : (_jsx(StyledGridLine, { x1: resolvedMargin.left + tickPosition, x2: resolvedMargin.left + tickPosition, y1: resolvedMargin.top, y2: resolvedMargin.top + plotHeight }, `grid-${tick}`));
380
- }), showAxisLines && (_jsx(_Fragment, { children: orientation === "vertical" ? (_jsxs(_Fragment, { children: [_jsx(StyledAxisLine, { x1: resolvedMargin.left, x2: resolvedMargin.left, y1: resolvedMargin.top, y2: resolvedMargin.top + plotHeight }), _jsx(StyledAxisLine, { x1: resolvedMargin.left, x2: resolvedMargin.left + plotWidth, y1: resolvedMargin.top + zeroPosition, y2: resolvedMargin.top + zeroPosition })] })) : (_jsxs(_Fragment, { children: [_jsx(StyledAxisLine, { x1: resolvedMargin.left, x2: resolvedMargin.left + plotWidth, y1: resolvedMargin.top + plotHeight, y2: resolvedMargin.top + plotHeight }), _jsx(StyledAxisLine, { x1: resolvedMargin.left + zeroPosition, x2: resolvedMargin.left + zeroPosition, y1: resolvedMargin.top, y2: resolvedMargin.top + plotHeight })] })) })), showValueAxisLabels &&
381
- tickValues.map((tick) => {
382
- const tickPosition = valueScale(tick);
383
- return orientation === "vertical" ? (_jsx(StyledAxisText, { x: resolvedMargin.left - 10, y: resolvedMargin.top + tickPosition, textAnchor: "end", dominantBaseline: "middle", children: formatTick(tick) }, `value-tick-${tick}`)) : (_jsx(StyledAxisText, { x: resolvedMargin.left + tickPosition, y: resolvedMargin.top + plotHeight + 18, textAnchor: "middle", children: formatTick(tick) }, `value-tick-${tick}`));
384
- }), categories.map((category) => {
385
- var _a;
386
- const categoryBandStart = (_a = categoryScale(category.key)) !== null && _a !== void 0 ? _a : 0;
387
- return category.bars.map((bar) => {
388
- var _a, _b, _c;
389
- const groupBandStart = (_a = groupScale === null || groupScale === void 0 ? void 0 : groupScale(String(bar.seriesKey))) !== null && _a !== void 0 ? _a : 0;
390
- const groupBandWidth = (_b = groupScale === null || groupScale === void 0 ? void 0 : groupScale.bandwidth()) !== null && _b !== void 0 ? _b : categoryScale.bandwidth();
391
- const thickness = safeMaxBarThickness
392
- ? Math.min(groupBandWidth, safeMaxBarThickness)
393
- : groupBandWidth;
394
- const thicknessOffset = (groupBandWidth - thickness) / 2;
395
- const animationProgress = getBarAnimationProgress(bar.renderIndex);
396
- const startPosition = valueScale(bar.valueStart);
397
- const endPosition = valueScale(bar.valueEnd);
398
- const animatedStartPosition = zeroPosition +
399
- (startPosition - zeroPosition) * animationProgress;
400
- const animatedEndPosition = zeroPosition + (endPosition - zeroPosition) * animationProgress;
401
- const x = orientation === "vertical"
402
- ? resolvedMargin.left +
403
- categoryBandStart +
404
- groupBandStart +
405
- thicknessOffset
406
- : resolvedMargin.left +
407
- Math.min(animatedStartPosition, animatedEndPosition);
408
- const y = orientation === "vertical"
409
- ? resolvedMargin.top +
410
- Math.min(animatedStartPosition, animatedEndPosition)
411
- : resolvedMargin.top +
412
- categoryBandStart +
413
- groupBandStart +
414
- thicknessOffset;
415
- const barWidth = orientation === "vertical"
416
- ? thickness
417
- : Math.abs(animatedEndPosition - animatedStartPosition);
418
- const barHeight = orientation === "vertical"
419
- ? Math.abs(animatedEndPosition - animatedStartPosition)
420
- : thickness;
421
- const isStackTerminal = seriesLayout !== "stacked" ||
422
- stackTerminalBarKeys.has(String(bar.key));
423
- const path = getRoundedBarPath({
424
- x,
425
- y,
426
- width: barWidth,
427
- height: barHeight,
428
- radius: isStackTerminal ? safeBarRadius : 0,
429
- orientation,
430
- value: bar.value,
431
- });
432
- const isPositive = bar.value >= 0;
433
- const outerValuePosition = valueScale(bar.valueEnd);
434
- const valueLabelX = orientation === "vertical"
435
- ? resolvedMargin.left +
436
- categoryBandStart +
437
- groupBandStart +
438
- thicknessOffset +
439
- thickness / 2
440
- : resolvedMargin.left +
441
- (isPositive
442
- ? Math.max(outerValuePosition, zeroPosition) + 8
443
- : Math.min(outerValuePosition, zeroPosition) - 8);
444
- const valueLabelY = orientation === "vertical"
445
- ? resolvedMargin.top +
446
- (isPositive
447
- ? Math.min(outerValuePosition, zeroPosition) - 8
448
- : Math.max(outerValuePosition, zeroPosition) + 14)
449
- : resolvedMargin.top +
450
- categoryBandStart +
451
- groupBandStart +
452
- thicknessOffset +
453
- thickness / 2;
454
- const shouldShowValueLabel = showLabels &&
455
- animationProgress >= 0.92 &&
456
- (seriesLayout !== "stacked" || isStackTerminal);
457
- const isActive = activeBarKey === bar.key ||
458
- (isMultiSeries && activeSeriesKey === bar.seriesKey);
459
- return (_jsxs("g", { children: [_jsx(StyledBar, { "$active": isActive, d: path || undefined, fill: bar.color, fillOpacity: resolvedBarOpacity, stroke: resolvedBarBorderColor, strokeWidth: resolvedBarBorderWidth, strokeOpacity: resolvedBarBorderOpacity, tabIndex: 0, "aria-label": isMultiSeries
460
- ? `${bar.seriesLabelText}, ${bar.categoryLabel}: ${formatDefaultValue(bar.value)}`
461
- : `${bar.label}: ${formatDefaultValue(bar.value)}`, onFocus: () => {
462
- setActiveBarKey(bar.key);
463
- setActiveSeriesKey(bar.seriesKey);
464
- }, onBlur: () => {
465
- setActiveBarKey(null);
466
- setActiveSeriesKey(null);
467
- }, onMouseEnter: (event) => {
468
- setActiveBarKey(bar.key);
469
- setActiveSeriesKey(bar.seriesKey);
470
- updateTooltipPosition(event, bar.key);
471
- }, onMouseMove: (event) => updateTooltipPosition(event, bar.key), onMouseLeave: () => {
472
- setActiveBarKey(null);
473
- setActiveSeriesKey(null);
474
- setActiveTooltip(null);
475
- }, onClick: (event) => onBarClick === null || onBarClick === void 0 ? void 0 : onBarClick(event, bar, bar.sourceSeries), onKeyDown: (event) => {
476
- if (event.key !== "Enter" && event.key !== " ")
477
- return;
478
- event.preventDefault();
479
- onBarClick === null || onBarClick === void 0 ? void 0 : onBarClick(event, bar, bar.sourceSeries);
480
- } }), shouldShowValueLabel && (_jsx(StyledValueLabel, { x: valueLabelX, y: valueLabelY, textAnchor: orientation === "vertical"
481
- ? "middle"
482
- : isPositive
483
- ? "start"
484
- : "end", dominantBaseline: orientation === "vertical" ? "middle" : "central", children: (_c = labelFormatter === null || labelFormatter === void 0 ? void 0 : labelFormatter(bar, bar.index, bar.sourceSeries)) !== null && _c !== void 0 ? _c : formatValue(bar, bar.sourceSeries) }))] }, bar.key));
485
- });
486
- }), showCategoryAxisLabels &&
487
- categories.map((category) => {
488
- var _a, _b;
489
- return orientation === "vertical" ? (_jsx(StyledAxisText, { x: resolvedMargin.left +
490
- ((_a = categoryScale(category.key)) !== null && _a !== void 0 ? _a : 0) +
491
- categoryScale.bandwidth() / 2, y: resolvedMargin.top + plotHeight + 20, textAnchor: "middle", children: formatCategoryLabel(category) }, `category-${category.key}`)) : (_jsx(StyledAxisText, { x: resolvedMargin.left - 10, y: resolvedMargin.top +
492
- ((_b = categoryScale(category.key)) !== null && _b !== void 0 ? _b : 0) +
493
- categoryScale.bandwidth() / 2, textAnchor: "end", dominantBaseline: "middle", children: formatCategoryLabel(category) }, `category-${category.key}`));
494
- })] }) }) })), activeTooltip && activeTooltipBar && tooltipStyle && (_jsx(StyledTooltip, { ref: tooltipRef, style: tooltipStyle, children: tooltipFormatter ? (tooltipFormatter(activeTooltipBar, activeTooltipBar.index, activeTooltipBar.sourceSeries)) : isMultiSeries && activeTooltipCategory ? (_jsxs(_Fragment, { children: [_jsx(StyledTooltipHeader, { children: _jsx(StyledTooltipLabel, { children: activeTooltipCategory.label }) }), _jsxs(StyledTooltipMeta, { children: [formatDefaultValue(activeTooltipCategory.bars.reduce((sum, bar) => sum + bar.value, 0)), " ", "total"] }), _jsx(StyledTooltipList, { children: activeTooltipCategory.bars.map((bar) => (_jsxs(StyledTooltipRow, { children: [_jsx(StyledTooltipSwatch, { "$color": bar.color }), _jsx(StyledTooltipLabel, { children: bar.seriesLabel }), _jsx(StyledTooltipValue, { children: formatValue(bar, bar.sourceSeries) })] }, `tooltip-${bar.key}`))) })] })) : (_jsxs(_Fragment, { children: [_jsxs(StyledTooltipHeader, { children: [_jsx(StyledTooltipSwatch, { "$color": activeTooltipBar.color }), _jsx(StyledTooltipLabel, { children: activeTooltipBar.label })] }), _jsx(StyledTooltipMeta, { children: formatValue(activeTooltipBar, activeTooltipBar.sourceSeries) })] })) })), shouldShowLegend && (_jsx(StyledLegend, { children: isMultiSeries
495
- ? resolvedSeries.map((seriesEntry) => (_jsxs(StyledLegendItem, { "$active": activeSeriesKey === seriesEntry.key, "$showSwatch": showLegendSwatches, "$showLabel": showLegendLabels, "$showValue": showLegendValues, tabIndex: 0, onMouseEnter: () => setActiveSeriesKey(seriesEntry.key), onMouseLeave: () => setActiveSeriesKey(null), onFocus: () => setActiveSeriesKey(seriesEntry.key), onBlur: () => setActiveSeriesKey(null), onClick: (event) => seriesEntry.sourceSeries &&
496
- (onSeriesLegendItemClick === null || onSeriesLegendItemClick === void 0 ? void 0 : onSeriesLegendItemClick(event, seriesEntry.sourceSeries)), onKeyDown: (event) => {
497
- if (event.key !== "Enter" && event.key !== " ")
498
- return;
499
- event.preventDefault();
500
- if (seriesEntry.sourceSeries) {
501
- onSeriesLegendItemClick === null || onSeriesLegendItemClick === void 0 ? void 0 : onSeriesLegendItemClick(event, seriesEntry.sourceSeries);
502
- }
503
- }, children: [showLegendSwatches && _jsx(StyledSwatch, { "$color": seriesEntry.color }), showLegendLabels && (_jsx(StyledLegendLabel, { children: seriesEntry.label })), showLegendValues && (_jsx(StyledLegendValue, { children: formatSeriesValue(seriesEntry) }))] }, `legend-${seriesEntry.key}`)))
504
- : bars.map((bar) => (_jsxs(StyledLegendItem, { "$active": activeBarKey === bar.key, "$showSwatch": showLegendSwatches, "$showLabel": showLegendLabels, "$showValue": showLegendValues, tabIndex: 0, onMouseEnter: () => setActiveBarKey(bar.key), onMouseLeave: () => setActiveBarKey(null), onFocus: () => setActiveBarKey(bar.key), onBlur: () => setActiveBarKey(null), onClick: (event) => onLegendItemClick === null || onLegendItemClick === void 0 ? void 0 : onLegendItemClick(event, bar), onKeyDown: (event) => {
505
- if (event.key !== "Enter" && event.key !== " ")
506
- return;
507
- event.preventDefault();
508
- onLegendItemClick === null || onLegendItemClick === void 0 ? void 0 : onLegendItemClick(event, bar);
509
- }, children: [showLegendSwatches && _jsx(StyledSwatch, { "$color": bar.color }), showLegendLabels && _jsx(StyledLegendLabel, { children: bar.label }), showLegendValues && (_jsx(StyledLegendValue, { children: formatValue(bar, bar.sourceSeries) }))] }, bar.key))) }))] })));
510
- };
511
- export default BarChart;
@@ -1,31 +0,0 @@
1
- import { ReactNode } from "react";
2
- import { clamp, easeOutCubic, formatDefaultValue, getGradientColor, getGradientColorFromStops, getGradientStops, mixColors } from "../ChartUtils";
3
- import { BarChartDatum, BarChartMargin, BarChartOrientation, BarChartSeries } from "./BarChart.types";
4
- export { clamp, easeOutCubic, formatDefaultValue, getGradientColor, getGradientColorFromStops, getGradientStops, mixColors, };
5
- export declare const getBarKey: (datum: BarChartDatum<unknown>, index: number) => string | number;
6
- export declare const getSeriesKey: (series: BarChartSeries<unknown>, index: number) => string | number;
7
- export declare const getSeriesLabelText: (label: ReactNode, fallbackLabel: string) => string;
8
- export declare const getCategoryKey: (datum: BarChartDatum<unknown>) => string;
9
- export declare const useThemeColors: (colors?: string[]) => string[];
10
- export declare const getBandPadding: (barGap: number, span: number, count: number) => {
11
- inner: number;
12
- outer: number;
13
- };
14
- export declare const getValueDomain: (values: number[], minValue?: number, maxValue?: number) => [number, number];
15
- export declare const getDefaultMargin: (orientation: BarChartOrientation, showCategoryAxisLabels: boolean, showValueAxisLabels: boolean, showLabels: boolean) => BarChartMargin;
16
- export declare const mergeChartMargin: (orientation: BarChartOrientation, margin: Partial<BarChartMargin> | undefined, showCategoryAxisLabels: boolean, showValueAxisLabels: boolean, showLabels: boolean) => {
17
- top: number;
18
- right: number;
19
- bottom: number;
20
- left: number;
21
- };
22
- export declare const normalizeTickValue: (value: number) => number;
23
- export declare const getRoundedBarPath: ({ x, y, width, height, radius, orientation, value, }: {
24
- x: number;
25
- y: number;
26
- width: number;
27
- height: number;
28
- radius: number;
29
- orientation: BarChartOrientation;
30
- value: number;
31
- }) => string;