@hero-design/rn 8.100.2 → 8.101.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 (39) hide show
  1. package/.turbo/turbo-build.log +3 -3
  2. package/CHANGELOG.md +12 -0
  3. package/es/index.js +111 -27
  4. package/lib/index.js +111 -27
  5. package/package.json +1 -1
  6. package/src/components/Chart/ColumnChart/ColumnChartContent.tsx +19 -3
  7. package/src/components/Chart/ColumnChart/Segment.tsx +1 -1
  8. package/src/components/Chart/ColumnChart/StackedSegment.tsx +10 -6
  9. package/src/components/Chart/ColumnChart/__tests__/Segment.spec.tsx +1 -1
  10. package/src/components/Chart/ColumnChart/__tests__/__snapshots__/StackedSegment.spec.tsx.snap +6 -21
  11. package/src/components/Chart/ColumnChart/__tests__/__snapshots__/index.spec.tsx.snap +999 -6
  12. package/src/components/Chart/ColumnChart/__tests__/index.spec.tsx +107 -0
  13. package/src/components/Chart/ColumnChart/index.tsx +15 -0
  14. package/src/components/Chart/Line/Line.tsx +5 -2
  15. package/src/components/Chart/Line/__tests__/Line.spec.tsx +13 -6
  16. package/src/components/Chart/Line/__tests__/__snapshots__/Line.spec.tsx.snap +1 -1
  17. package/src/components/Chart/Line/__tests__/__snapshots__/index.spec.tsx.snap +1464 -4
  18. package/src/components/Chart/Line/__tests__/index.spec.tsx +95 -1
  19. package/src/components/Chart/Line/index.tsx +14 -2
  20. package/src/components/Chart/shared/__tests__/utils.spec.ts +16 -0
  21. package/src/components/Chart/shared/constants.ts +4 -0
  22. package/src/components/Chart/shared/hooks/useCustomColor.ts +84 -0
  23. package/src/components/Chart/shared/utils.ts +14 -0
  24. package/src/components/Chart/types.ts +32 -0
  25. package/src/components/StatusScreens/Empty/__tests__/__snapshots__/index.spec.tsx.snap +8 -35
  26. package/src/components/StatusScreens/Empty/index.tsx +7 -3
  27. package/stats/8.100.2/rn-stats.html +1 -3
  28. package/stats/8.101.0/rn-stats.html +4842 -0
  29. package/stats/8.101.1/rn-stats.html +4844 -0
  30. package/types/components/Chart/ColumnChart/ColumnChartContent.d.ts +5 -1
  31. package/types/components/Chart/ColumnChart/StackedSegment.d.ts +4 -0
  32. package/types/components/Chart/ColumnChart/index.d.ts +8 -2
  33. package/types/components/Chart/Line/Line.d.ts +3 -1
  34. package/types/components/Chart/Line/index.d.ts +8 -2
  35. package/types/components/Chart/index.d.ts +2 -2
  36. package/types/components/Chart/shared/constants.d.ts +2 -0
  37. package/types/components/Chart/shared/hooks/useCustomColor.d.ts +22 -0
  38. package/types/components/Chart/shared/utils.d.ts +11 -0
  39. package/types/components/Chart/types.d.ts +14 -1
@@ -1,4 +1,4 @@
1
- (node:3250) ExperimentalWarning: Importing JSON modules is an experimental feature and might change at any time
1
+ (node:3245) ExperimentalWarning: Importing JSON modules is an experimental feature and might change at any time
2
2
  (Use `node --trace-warnings ...` to show where the warning was created)
3
3
  
4
4
  src/index.ts → lib/index.js, es/index.js...
@@ -15,9 +15,9 @@ node_modules/d3-selection/src/selection/index.js -> node_modules/d3-selection/sr
15
15
     ~~~~~~~~~~~~~~~~~~~
16
16
  
17
17
  (!) [plugin node-resolve] preferring built-in module 'events' over local alternative at '/home/runner/work/hero-design/hero-design/node_modules/events/events.js', pass 'preferBuiltins: false' to disable this behavior or 'preferBuiltins: true' to disable this warning.or passing a function to 'preferBuiltins' to provide more fine-grained control over which built-in modules to prefer.
18
- created lib/index.js, es/index.js in 1m 11.4s
18
+ created lib/index.js, es/index.js in 1m 14s
19
19
  
20
20
  /home/runner/work/hero-design/hero-design/packages/rn/src/locales/en_AU.ts, /home/runner/work/hero-design/hero-design/packages/rn/src/locales/en_CA.ts, /home/runner/work/hero-design/hero-design/packages/rn/src/locales/index.ts, /home/runner/work/hero-design/hero-design/packages/rn/src/locales/types.ts → ., ....
21
21
  (!) Generated empty chunks
22
22
  "locales/types" and "locales/types"
23
- created ., . in 20.7s
23
+ created ., . in 22.7s
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @hero-design/rn
2
2
 
3
+ ## 8.101.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#3951](https://github.com/Thinkei/hero-design/pull/3951) [`0145a0dd1ca1ad57ce1d4848821c937b236fb408`](https://github.com/Thinkei/hero-design/commit/0145a0dd1ca1ad57ce1d4848821c937b236fb408) Thanks [@ttkien](https://github.com/ttkien)! - [Empty] internal fix title, remove Typography-wrapper if React title is React Element
8
+
9
+ ## 8.101.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [#3943](https://github.com/Thinkei/hero-design/pull/3943) [`0eb5957f1c9ff674700266e0c3c460532c369b49`](https://github.com/Thinkei/hero-design/commit/0eb5957f1c9ff674700266e0c3c460532c369b49) Thanks [@vinhphan-eh](https://github.com/vinhphan-eh)! - [Chart] Support custom color config
14
+
3
15
  ## 8.100.2
4
16
 
5
17
  ### Patch Changes
package/es/index.js CHANGED
@@ -1785,14 +1785,14 @@ var palette$8 = {
1785
1785
  maasstrichtBlueLight35: maasstrichtBlue$1.lighten35,
1786
1786
  maasstrichtBlueLight40: maasstrichtBlue$1.lighten40,
1787
1787
  // Update 23 May 2025
1788
- primaryLite: mauve$3.base,
1789
- blueLite: blue$2.base,
1790
- greenLite: grotesqueGreen.darken10,
1791
- redLite: pastelRed.lighten25,
1792
- orangeLite: blazingBonfire.lighten30,
1793
- yellowLite: yellow$2.base,
1794
- pinkLite: pink$2.lighten40,
1795
- greyLite: cumberlandFog.darken15,
1788
+ primaryLight: mauve$3.base,
1789
+ blueLight: blue$2.base,
1790
+ greenLight: grotesqueGreen.darken10,
1791
+ redLight: pastelRed.lighten25,
1792
+ orangeLight: blazingBonfire.lighten30,
1793
+ yellowLight: yellow$2.base,
1794
+ pinkLight: pink$2.lighten40,
1795
+ greyLight: cumberlandFog.darken15,
1796
1796
  primaryMedium: violet$2.lighten20,
1797
1797
  blueMedium: ultramarineBlue.base,
1798
1798
  greenMedium: green$2.base,
@@ -18672,6 +18672,8 @@ var XAxis = function XAxis(_ref) {
18672
18672
 
18673
18673
  var DASH_ARRAY = [4, 4];
18674
18674
  var DEFAULT_LINE_STROKE_WIDTH = 2;
18675
+ var ERROR_COLOR_NUMBER_MISMATCH = 'styleConfig.series should have exact number of colors as the number of labels';
18676
+ var ERROR_COLOR_NOT_FOUND = 'Color {color} not found in the mobile visualization palette.';
18675
18677
 
18676
18678
  var XAxisGrid = function XAxisGrid(_ref) {
18677
18679
  var xAxisConfig = _ref.xAxisConfig,
@@ -18935,6 +18937,17 @@ var ChartFrame = function ChartFrame(_ref) {
18935
18937
  }))));
18936
18938
  };
18937
18939
 
18940
+ /**
18941
+ * Filter elements that have no color.
18942
+ * @param data - The data to filter.
18943
+ * @returns The filtered data.
18944
+ */
18945
+ var filterElementHasNoColor = function filterElementHasNoColor(data) {
18946
+ return data.filter(function (element) {
18947
+ return element.color !== undefined;
18948
+ });
18949
+ };
18950
+
18938
18951
  // Only use colors that are not maasstrichtBlue
18939
18952
  var DEFAULT_COLORS = Object.entries(palette$8).filter(function (_ref) {
18940
18953
  var _ref2 = _slicedToArray(_ref, 1),
@@ -18953,11 +18966,70 @@ var DEFAULT_COLORS = Object.entries(palette$8).filter(function (_ref) {
18953
18966
  */
18954
18967
  function useColorScale(labels, customColors) {
18955
18968
  return useMemo(function () {
18956
- var palette = DEFAULT_COLORS;
18969
+ var palette = customColors && customColors.length > 0 ? customColors : DEFAULT_COLORS;
18957
18970
  return ordinal().domain(labels).range(palette);
18958
18971
  }, [labels, customColors]);
18959
18972
  }
18960
18973
 
18974
+ /**
18975
+ * Hook to handle custom color assignments for chart series
18976
+ *
18977
+ * This hook manages:
18978
+ * 1. Validation of custom color configurations
18979
+ * 2. Color mapping between series and palette
18980
+ * 3. Fallback to default colors when custom colors aren't provided
18981
+ *
18982
+ * @throws {Error} When custom colors are invalid or don't match data series
18983
+ */
18984
+ var useCustomColor = function useCustomColor(_ref) {
18985
+ var data = _ref.data,
18986
+ seriesConfig = _ref.seriesConfig;
18987
+ // Check if custom colors are provided and non-empty
18988
+ var hasCustomColors = Boolean(seriesConfig === null || seriesConfig === void 0 ? void 0 : seriesConfig.length);
18989
+ // Process and validate custom color segments
18990
+ var customSegments = useMemo(function () {
18991
+ if (!hasCustomColors) return undefined;
18992
+ // Filter out segments without colors
18993
+ var filtered = filterElementHasNoColor(seriesConfig || []);
18994
+ // Validate: number of custom colors must match number of data series
18995
+ if (filtered.length < data.length) {
18996
+ throw new Error(ERROR_COLOR_NUMBER_MISMATCH);
18997
+ }
18998
+ // Validate: all data series must have corresponding custom colors
18999
+ var dataLabels = new Set(data.map(function (d) {
19000
+ return d.label;
19001
+ }));
19002
+ if (!filtered.every(function (series) {
19003
+ return dataLabels.has(series.label);
19004
+ })) {
19005
+ throw new Error(ERROR_COLOR_NUMBER_MISMATCH);
19006
+ }
19007
+ return filtered;
19008
+ }, [seriesConfig, hasCustomColors, data]);
19009
+ // Map custom segments to actual color values from palette
19010
+ var customColors = useMemo(function () {
19011
+ if (!customSegments) return [];
19012
+ // Convert color keys to actual color values
19013
+ var colors = customSegments.map(function (series) {
19014
+ var color = palette$8[series.color];
19015
+ // Validate: color key must exist in palette
19016
+ if (color === undefined) {
19017
+ throw new Error(ERROR_COLOR_NOT_FOUND.replace('{color}', series.color));
19018
+ }
19019
+ return color;
19020
+ });
19021
+ return colors;
19022
+ }, [customSegments]);
19023
+ // Create color scale:
19024
+ // - If custom colors exist, use custom color mapping
19025
+ // - Otherwise, fall back to default color mapping
19026
+ return useColorScale(customSegments ? customSegments.map(function (series) {
19027
+ return series.label;
19028
+ }) : data.map(function (series) {
19029
+ return series.label;
19030
+ }), customColors);
19031
+ };
19032
+
18961
19033
  /**
18962
19034
  * Finds a "nice" number approximately equal to x.
18963
19035
  * https://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks
@@ -19027,7 +19099,8 @@ var Line = function Line(_ref) {
19027
19099
  minValue = _ref.minValue,
19028
19100
  labels = _ref.labels,
19029
19101
  coordinates = _ref.coordinates,
19030
- color = _ref.color;
19102
+ color = _ref.color,
19103
+ testID = _ref.testID;
19031
19104
  var xStart = coordinates.xStart,
19032
19105
  xEnd = coordinates.xEnd,
19033
19106
  yStart = coordinates.yStart,
@@ -19059,8 +19132,8 @@ var Line = function Line(_ref) {
19059
19132
  return lineGenerator(data);
19060
19133
  }, [data, lineGenerator]);
19061
19134
  return pathData ? /*#__PURE__*/React__default.createElement(Path$1, {
19062
- testID: "line-path",
19063
- accessibilityLabel: "chart-line-maxValue:".concat(maxValue, ",minValue:").concat(minValue, ",labelsLength:").concat(labels.length),
19135
+ testID: testID,
19136
+ accessibilityLabel: "chart-line-maxValue:".concat(maxValue, ",minValue:").concat(minValue, ",labelsLength:").concat(labels.length, ",color:").concat(color),
19064
19137
  d: pathData,
19065
19138
  stroke: color || theme.colors.secondary,
19066
19139
  strokeWidth: DEFAULT_LINE_STROKE_WIDTH,
@@ -19078,7 +19151,8 @@ var LineChart = function LineChart(_ref) {
19078
19151
  style = _ref.style,
19079
19152
  testID = _ref.testID,
19080
19153
  headerConfig = _ref.headerConfig,
19081
- emptyText = _ref.emptyText;
19154
+ emptyText = _ref.emptyText,
19155
+ styleConfig = _ref.styleConfig;
19082
19156
  var _useState = useState({
19083
19157
  width: 0,
19084
19158
  height: 0
@@ -19086,9 +19160,10 @@ var LineChart = function LineChart(_ref) {
19086
19160
  _useState2 = _slicedToArray(_useState, 2),
19087
19161
  chartSize = _useState2[0],
19088
19162
  setChartSize = _useState2[1];
19089
- var colorScale = useColorScale(data.map(function (series) {
19090
- return series.label;
19091
- }));
19163
+ var colorScale = useCustomColor({
19164
+ data: data,
19165
+ seriesConfig: styleConfig === null || styleConfig === void 0 ? void 0 : styleConfig.series
19166
+ });
19092
19167
  var niceValues = useMemo(function () {
19093
19168
  var maxDataValue = maxValueFromDataSet(data);
19094
19169
  var minDataValue = minValueFromDataSet(data);
@@ -19129,6 +19204,7 @@ var LineChart = function LineChart(_ref) {
19129
19204
  var _calculatedXAxisConfi;
19130
19205
  return /*#__PURE__*/React__default.createElement(Line, {
19131
19206
  color: colorScale(series.label),
19207
+ testID: "line-".concat(series.label),
19132
19208
  key: series.label,
19133
19209
  data: series.data,
19134
19210
  coordinates: coordinates,
@@ -19195,7 +19271,7 @@ var Segment = function Segment(_ref) {
19195
19271
  height: adjustedHeight,
19196
19272
  rx: width / 2,
19197
19273
  fill: color,
19198
- accessibilityLabel: "Column segment: value ".concat(value, ", x-label ").concat(xLabel, ", series ").concat(seriesLabel),
19274
+ accessibilityLabel: "Column segment: value ".concat(value, ", x-label ").concat(xLabel, ", series ").concat(seriesLabel, ", color ").concat(color),
19199
19275
  testID: testID,
19200
19276
  onPress: onPress
19201
19277
  });
@@ -19219,7 +19295,8 @@ var StackedSegment = function StackedSegment(_ref) {
19219
19295
  coordinates = _ref.coordinates,
19220
19296
  xCenter = _ref.xCenter,
19221
19297
  xIndex = _ref.xIndex,
19222
- onBarPress = _ref.onBarPress;
19298
+ onBarPress = _ref.onBarPress,
19299
+ colorScale = _ref.colorScale;
19223
19300
  var yStart = coordinates.yStart,
19224
19301
  yEnd = coordinates.yEnd;
19225
19302
  var stackedMaxY = (_yAxisConfig$maxValue = yAxisConfig.maxValue) !== null && _yAxisConfig$maxValue !== void 0 ? _yAxisConfig$maxValue : 0;
@@ -19230,7 +19307,6 @@ var StackedSegment = function StackedSegment(_ref) {
19230
19307
  yEnd: yEnd
19231
19308
  });
19232
19309
  var yStack = 0; // running sum for stacking
19233
- var colorScale = useColorScale(seriesLabels);
19234
19310
  return stackedData.map(function (value, index) {
19235
19311
  // If value is undefined, skip this segment
19236
19312
  if (value === undefined) {
@@ -19248,7 +19324,7 @@ var StackedSegment = function StackedSegment(_ref) {
19248
19324
  xCenter: xCenter,
19249
19325
  y: y1,
19250
19326
  height: colHeight,
19251
- color: colorScale(seriesLabel),
19327
+ color: colorScale === null || colorScale === void 0 ? void 0 : colorScale(seriesLabel),
19252
19328
  value: value,
19253
19329
  xLabel: xLabel,
19254
19330
  seriesLabel: seriesLabel,
@@ -19281,7 +19357,8 @@ var ColumnChartContent = function ColumnChartContent(_ref) {
19281
19357
  data = _ref.data,
19282
19358
  yAxisConfig = _ref.yAxisConfig,
19283
19359
  xAxisConfig = _ref.xAxisConfig,
19284
- onBarPress = _ref.onBarPress;
19360
+ onBarPress = _ref.onBarPress,
19361
+ colorScale = _ref.colorScale;
19285
19362
  var yStart = coordinates.yStart,
19286
19363
  yEnd = coordinates.yEnd,
19287
19364
  xStart = coordinates.xStart,
@@ -19319,10 +19396,11 @@ var ColumnChartContent = function ColumnChartContent(_ref) {
19319
19396
  xCenter: x + scaleX.bandwidth() / 2,
19320
19397
  seriesLabels: seriesLabels,
19321
19398
  xIndex: xIdx,
19322
- onBarPress: onBarPress
19399
+ onBarPress: onBarPress,
19400
+ colorScale: colorScale
19323
19401
  });
19324
19402
  });
19325
- }, [xLabels, data, xStart, yStart, xEnd, yEnd, onBarPress, yAxisConfig]);
19403
+ }, [xLabels, data, xStart, yStart, xEnd, yEnd, onBarPress, yAxisConfig, colorScale]);
19326
19404
  return /*#__PURE__*/React__default.createElement(G, {
19327
19405
  testID: "column-chart-content"
19328
19406
  }, columns);
@@ -19365,7 +19443,12 @@ var ColumnChart = function ColumnChart(_ref) {
19365
19443
  testID = _ref.testID,
19366
19444
  headerConfig = _ref.headerConfig,
19367
19445
  emptyText = _ref.emptyText,
19368
- onBarPress = _ref.onBarPress;
19446
+ onBarPress = _ref.onBarPress,
19447
+ styleConfig = _ref.styleConfig;
19448
+ var colorScale = useCustomColor({
19449
+ data: data,
19450
+ seriesConfig: styleConfig === null || styleConfig === void 0 ? void 0 : styleConfig.series
19451
+ });
19369
19452
  var xLabels = useMemo(function () {
19370
19453
  var _data$;
19371
19454
  return xAxisConfig.labels && xAxisConfig.labels.length > 0 ? xAxisConfig.labels : ((_data$ = data[0]) === null || _data$ === void 0 ? void 0 : _data$.data.map(function (_, index) {
@@ -19459,7 +19542,8 @@ var ColumnChart = function ColumnChart(_ref) {
19459
19542
  data: data,
19460
19543
  xAxisConfig: calculatedXAxisConfig,
19461
19544
  yAxisConfig: calculatedYAxisConfig,
19462
- onBarPress: onBarPress
19545
+ onBarPress: onBarPress,
19546
+ colorScale: colorScale
19463
19547
  });
19464
19548
  }
19465
19549
  }));
@@ -21779,11 +21863,11 @@ var Empty = function Empty(_ref2) {
21779
21863
  }, renderImageOrIcon$2({
21780
21864
  image: image,
21781
21865
  icon: icon
21782
- }), /*#__PURE__*/React__default.createElement(StyledTitle, {
21866
+ }), typeof title === 'string' ? /*#__PURE__*/React__default.createElement(StyledTitle, {
21783
21867
  themeVariant: variant,
21784
21868
  level: "h4",
21785
21869
  typeface: "playful"
21786
- }, title), !!description && /*#__PURE__*/React__default.createElement(StyledDescription, {
21870
+ }, title) : title, !!description && /*#__PURE__*/React__default.createElement(StyledDescription, {
21787
21871
  variant: "small",
21788
21872
  themeVariant: variant
21789
21873
  }, description));
package/lib/index.js CHANGED
@@ -1814,14 +1814,14 @@ var palette$8 = {
1814
1814
  maasstrichtBlueLight35: maasstrichtBlue$1.lighten35,
1815
1815
  maasstrichtBlueLight40: maasstrichtBlue$1.lighten40,
1816
1816
  // Update 23 May 2025
1817
- primaryLite: mauve$3.base,
1818
- blueLite: blue$2.base,
1819
- greenLite: grotesqueGreen.darken10,
1820
- redLite: pastelRed.lighten25,
1821
- orangeLite: blazingBonfire.lighten30,
1822
- yellowLite: yellow$2.base,
1823
- pinkLite: pink$2.lighten40,
1824
- greyLite: cumberlandFog.darken15,
1817
+ primaryLight: mauve$3.base,
1818
+ blueLight: blue$2.base,
1819
+ greenLight: grotesqueGreen.darken10,
1820
+ redLight: pastelRed.lighten25,
1821
+ orangeLight: blazingBonfire.lighten30,
1822
+ yellowLight: yellow$2.base,
1823
+ pinkLight: pink$2.lighten40,
1824
+ greyLight: cumberlandFog.darken15,
1825
1825
  primaryMedium: violet$2.lighten20,
1826
1826
  blueMedium: ultramarineBlue.base,
1827
1827
  greenMedium: green$2.base,
@@ -18701,6 +18701,8 @@ var XAxis = function XAxis(_ref) {
18701
18701
 
18702
18702
  var DASH_ARRAY = [4, 4];
18703
18703
  var DEFAULT_LINE_STROKE_WIDTH = 2;
18704
+ var ERROR_COLOR_NUMBER_MISMATCH = 'styleConfig.series should have exact number of colors as the number of labels';
18705
+ var ERROR_COLOR_NOT_FOUND = 'Color {color} not found in the mobile visualization palette.';
18704
18706
 
18705
18707
  var XAxisGrid = function XAxisGrid(_ref) {
18706
18708
  var xAxisConfig = _ref.xAxisConfig,
@@ -18964,6 +18966,17 @@ var ChartFrame = function ChartFrame(_ref) {
18964
18966
  }))));
18965
18967
  };
18966
18968
 
18969
+ /**
18970
+ * Filter elements that have no color.
18971
+ * @param data - The data to filter.
18972
+ * @returns The filtered data.
18973
+ */
18974
+ var filterElementHasNoColor = function filterElementHasNoColor(data) {
18975
+ return data.filter(function (element) {
18976
+ return element.color !== undefined;
18977
+ });
18978
+ };
18979
+
18967
18980
  // Only use colors that are not maasstrichtBlue
18968
18981
  var DEFAULT_COLORS = Object.entries(palette$8).filter(function (_ref) {
18969
18982
  var _ref2 = _slicedToArray(_ref, 1),
@@ -18982,11 +18995,70 @@ var DEFAULT_COLORS = Object.entries(palette$8).filter(function (_ref) {
18982
18995
  */
18983
18996
  function useColorScale(labels, customColors) {
18984
18997
  return React.useMemo(function () {
18985
- var palette = DEFAULT_COLORS;
18998
+ var palette = customColors && customColors.length > 0 ? customColors : DEFAULT_COLORS;
18986
18999
  return ordinal().domain(labels).range(palette);
18987
19000
  }, [labels, customColors]);
18988
19001
  }
18989
19002
 
19003
+ /**
19004
+ * Hook to handle custom color assignments for chart series
19005
+ *
19006
+ * This hook manages:
19007
+ * 1. Validation of custom color configurations
19008
+ * 2. Color mapping between series and palette
19009
+ * 3. Fallback to default colors when custom colors aren't provided
19010
+ *
19011
+ * @throws {Error} When custom colors are invalid or don't match data series
19012
+ */
19013
+ var useCustomColor = function useCustomColor(_ref) {
19014
+ var data = _ref.data,
19015
+ seriesConfig = _ref.seriesConfig;
19016
+ // Check if custom colors are provided and non-empty
19017
+ var hasCustomColors = Boolean(seriesConfig === null || seriesConfig === void 0 ? void 0 : seriesConfig.length);
19018
+ // Process and validate custom color segments
19019
+ var customSegments = React.useMemo(function () {
19020
+ if (!hasCustomColors) return undefined;
19021
+ // Filter out segments without colors
19022
+ var filtered = filterElementHasNoColor(seriesConfig || []);
19023
+ // Validate: number of custom colors must match number of data series
19024
+ if (filtered.length < data.length) {
19025
+ throw new Error(ERROR_COLOR_NUMBER_MISMATCH);
19026
+ }
19027
+ // Validate: all data series must have corresponding custom colors
19028
+ var dataLabels = new Set(data.map(function (d) {
19029
+ return d.label;
19030
+ }));
19031
+ if (!filtered.every(function (series) {
19032
+ return dataLabels.has(series.label);
19033
+ })) {
19034
+ throw new Error(ERROR_COLOR_NUMBER_MISMATCH);
19035
+ }
19036
+ return filtered;
19037
+ }, [seriesConfig, hasCustomColors, data]);
19038
+ // Map custom segments to actual color values from palette
19039
+ var customColors = React.useMemo(function () {
19040
+ if (!customSegments) return [];
19041
+ // Convert color keys to actual color values
19042
+ var colors = customSegments.map(function (series) {
19043
+ var color = palette$8[series.color];
19044
+ // Validate: color key must exist in palette
19045
+ if (color === undefined) {
19046
+ throw new Error(ERROR_COLOR_NOT_FOUND.replace('{color}', series.color));
19047
+ }
19048
+ return color;
19049
+ });
19050
+ return colors;
19051
+ }, [customSegments]);
19052
+ // Create color scale:
19053
+ // - If custom colors exist, use custom color mapping
19054
+ // - Otherwise, fall back to default color mapping
19055
+ return useColorScale(customSegments ? customSegments.map(function (series) {
19056
+ return series.label;
19057
+ }) : data.map(function (series) {
19058
+ return series.label;
19059
+ }), customColors);
19060
+ };
19061
+
18990
19062
  /**
18991
19063
  * Finds a "nice" number approximately equal to x.
18992
19064
  * https://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks
@@ -19056,7 +19128,8 @@ var Line = function Line(_ref) {
19056
19128
  minValue = _ref.minValue,
19057
19129
  labels = _ref.labels,
19058
19130
  coordinates = _ref.coordinates,
19059
- color = _ref.color;
19131
+ color = _ref.color,
19132
+ testID = _ref.testID;
19060
19133
  var xStart = coordinates.xStart,
19061
19134
  xEnd = coordinates.xEnd,
19062
19135
  yStart = coordinates.yStart,
@@ -19088,8 +19161,8 @@ var Line = function Line(_ref) {
19088
19161
  return lineGenerator(data);
19089
19162
  }, [data, lineGenerator]);
19090
19163
  return pathData ? /*#__PURE__*/React__namespace.default.createElement(Svg.Path, {
19091
- testID: "line-path",
19092
- accessibilityLabel: "chart-line-maxValue:".concat(maxValue, ",minValue:").concat(minValue, ",labelsLength:").concat(labels.length),
19164
+ testID: testID,
19165
+ accessibilityLabel: "chart-line-maxValue:".concat(maxValue, ",minValue:").concat(minValue, ",labelsLength:").concat(labels.length, ",color:").concat(color),
19093
19166
  d: pathData,
19094
19167
  stroke: color || theme.colors.secondary,
19095
19168
  strokeWidth: DEFAULT_LINE_STROKE_WIDTH,
@@ -19107,7 +19180,8 @@ var LineChart = function LineChart(_ref) {
19107
19180
  style = _ref.style,
19108
19181
  testID = _ref.testID,
19109
19182
  headerConfig = _ref.headerConfig,
19110
- emptyText = _ref.emptyText;
19183
+ emptyText = _ref.emptyText,
19184
+ styleConfig = _ref.styleConfig;
19111
19185
  var _useState = React.useState({
19112
19186
  width: 0,
19113
19187
  height: 0
@@ -19115,9 +19189,10 @@ var LineChart = function LineChart(_ref) {
19115
19189
  _useState2 = _slicedToArray(_useState, 2),
19116
19190
  chartSize = _useState2[0],
19117
19191
  setChartSize = _useState2[1];
19118
- var colorScale = useColorScale(data.map(function (series) {
19119
- return series.label;
19120
- }));
19192
+ var colorScale = useCustomColor({
19193
+ data: data,
19194
+ seriesConfig: styleConfig === null || styleConfig === void 0 ? void 0 : styleConfig.series
19195
+ });
19121
19196
  var niceValues = React.useMemo(function () {
19122
19197
  var maxDataValue = maxValueFromDataSet(data);
19123
19198
  var minDataValue = minValueFromDataSet(data);
@@ -19158,6 +19233,7 @@ var LineChart = function LineChart(_ref) {
19158
19233
  var _calculatedXAxisConfi;
19159
19234
  return /*#__PURE__*/React__namespace.default.createElement(Line, {
19160
19235
  color: colorScale(series.label),
19236
+ testID: "line-".concat(series.label),
19161
19237
  key: series.label,
19162
19238
  data: series.data,
19163
19239
  coordinates: coordinates,
@@ -19224,7 +19300,7 @@ var Segment = function Segment(_ref) {
19224
19300
  height: adjustedHeight,
19225
19301
  rx: width / 2,
19226
19302
  fill: color,
19227
- accessibilityLabel: "Column segment: value ".concat(value, ", x-label ").concat(xLabel, ", series ").concat(seriesLabel),
19303
+ accessibilityLabel: "Column segment: value ".concat(value, ", x-label ").concat(xLabel, ", series ").concat(seriesLabel, ", color ").concat(color),
19228
19304
  testID: testID,
19229
19305
  onPress: onPress
19230
19306
  });
@@ -19248,7 +19324,8 @@ var StackedSegment = function StackedSegment(_ref) {
19248
19324
  coordinates = _ref.coordinates,
19249
19325
  xCenter = _ref.xCenter,
19250
19326
  xIndex = _ref.xIndex,
19251
- onBarPress = _ref.onBarPress;
19327
+ onBarPress = _ref.onBarPress,
19328
+ colorScale = _ref.colorScale;
19252
19329
  var yStart = coordinates.yStart,
19253
19330
  yEnd = coordinates.yEnd;
19254
19331
  var stackedMaxY = (_yAxisConfig$maxValue = yAxisConfig.maxValue) !== null && _yAxisConfig$maxValue !== void 0 ? _yAxisConfig$maxValue : 0;
@@ -19259,7 +19336,6 @@ var StackedSegment = function StackedSegment(_ref) {
19259
19336
  yEnd: yEnd
19260
19337
  });
19261
19338
  var yStack = 0; // running sum for stacking
19262
- var colorScale = useColorScale(seriesLabels);
19263
19339
  return stackedData.map(function (value, index) {
19264
19340
  // If value is undefined, skip this segment
19265
19341
  if (value === undefined) {
@@ -19277,7 +19353,7 @@ var StackedSegment = function StackedSegment(_ref) {
19277
19353
  xCenter: xCenter,
19278
19354
  y: y1,
19279
19355
  height: colHeight,
19280
- color: colorScale(seriesLabel),
19356
+ color: colorScale === null || colorScale === void 0 ? void 0 : colorScale(seriesLabel),
19281
19357
  value: value,
19282
19358
  xLabel: xLabel,
19283
19359
  seriesLabel: seriesLabel,
@@ -19310,7 +19386,8 @@ var ColumnChartContent = function ColumnChartContent(_ref) {
19310
19386
  data = _ref.data,
19311
19387
  yAxisConfig = _ref.yAxisConfig,
19312
19388
  xAxisConfig = _ref.xAxisConfig,
19313
- onBarPress = _ref.onBarPress;
19389
+ onBarPress = _ref.onBarPress,
19390
+ colorScale = _ref.colorScale;
19314
19391
  var yStart = coordinates.yStart,
19315
19392
  yEnd = coordinates.yEnd,
19316
19393
  xStart = coordinates.xStart,
@@ -19348,10 +19425,11 @@ var ColumnChartContent = function ColumnChartContent(_ref) {
19348
19425
  xCenter: x + scaleX.bandwidth() / 2,
19349
19426
  seriesLabels: seriesLabels,
19350
19427
  xIndex: xIdx,
19351
- onBarPress: onBarPress
19428
+ onBarPress: onBarPress,
19429
+ colorScale: colorScale
19352
19430
  });
19353
19431
  });
19354
- }, [xLabels, data, xStart, yStart, xEnd, yEnd, onBarPress, yAxisConfig]);
19432
+ }, [xLabels, data, xStart, yStart, xEnd, yEnd, onBarPress, yAxisConfig, colorScale]);
19355
19433
  return /*#__PURE__*/React__namespace.default.createElement(Svg.G, {
19356
19434
  testID: "column-chart-content"
19357
19435
  }, columns);
@@ -19394,7 +19472,12 @@ var ColumnChart = function ColumnChart(_ref) {
19394
19472
  testID = _ref.testID,
19395
19473
  headerConfig = _ref.headerConfig,
19396
19474
  emptyText = _ref.emptyText,
19397
- onBarPress = _ref.onBarPress;
19475
+ onBarPress = _ref.onBarPress,
19476
+ styleConfig = _ref.styleConfig;
19477
+ var colorScale = useCustomColor({
19478
+ data: data,
19479
+ seriesConfig: styleConfig === null || styleConfig === void 0 ? void 0 : styleConfig.series
19480
+ });
19398
19481
  var xLabels = React.useMemo(function () {
19399
19482
  var _data$;
19400
19483
  return xAxisConfig.labels && xAxisConfig.labels.length > 0 ? xAxisConfig.labels : ((_data$ = data[0]) === null || _data$ === void 0 ? void 0 : _data$.data.map(function (_, index) {
@@ -19488,7 +19571,8 @@ var ColumnChart = function ColumnChart(_ref) {
19488
19571
  data: data,
19489
19572
  xAxisConfig: calculatedXAxisConfig,
19490
19573
  yAxisConfig: calculatedYAxisConfig,
19491
- onBarPress: onBarPress
19574
+ onBarPress: onBarPress,
19575
+ colorScale: colorScale
19492
19576
  });
19493
19577
  }
19494
19578
  }));
@@ -21808,11 +21892,11 @@ var Empty = function Empty(_ref2) {
21808
21892
  }, renderImageOrIcon$2({
21809
21893
  image: image,
21810
21894
  icon: icon
21811
- }), /*#__PURE__*/React__namespace.default.createElement(StyledTitle, {
21895
+ }), typeof title === 'string' ? /*#__PURE__*/React__namespace.default.createElement(StyledTitle, {
21812
21896
  themeVariant: variant,
21813
21897
  level: "h4",
21814
21898
  typeface: "playful"
21815
- }, title), !!description && /*#__PURE__*/React__namespace.default.createElement(StyledDescription, {
21899
+ }, title) : title, !!description && /*#__PURE__*/React__namespace.default.createElement(StyledDescription, {
21816
21900
  variant: "small",
21817
21901
  themeVariant: variant
21818
21902
  }, description));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hero-design/rn",
3
- "version": "8.100.2",
3
+ "version": "8.101.1",
4
4
  "license": "MIT",
5
5
  "main": "lib/index.js",
6
6
  "module": "es/index.js",
@@ -4,10 +4,10 @@
4
4
 
5
5
  import React, { memo, useMemo } from 'react';
6
6
  import { G } from 'react-native-svg';
7
- import { DataValue, Series, XAxisConfig, YAxisConfig } from '../types';
7
+ import { deepCompareValue } from '../../../utils/helpers';
8
8
  import useScaleBandX from '../shared/hooks/useScaleBandX';
9
+ import { DataValue, Series, XAxisConfig, YAxisConfig } from '../types';
9
10
  import StackedSegment from './StackedSegment';
10
- import { deepCompareValue } from '../../../utils/helpers';
11
11
 
12
12
  interface ColumnChartContentProps {
13
13
  coordinates: { yStart: number; yEnd: number; xStart: number; xEnd: number };
@@ -24,6 +24,10 @@ interface ColumnChartContentProps {
24
24
  seriesIndex: number;
25
25
  xIndex: number;
26
26
  }) => void;
27
+ /**
28
+ * A function that maps series labels to colors.
29
+ */
30
+ colorScale?: (label: string) => string | undefined;
27
31
  }
28
32
 
29
33
  /**
@@ -37,6 +41,7 @@ const ColumnChartContent = ({
37
41
  yAxisConfig,
38
42
  xAxisConfig,
39
43
  onBarPress,
44
+ colorScale,
40
45
  }: ColumnChartContentProps) => {
41
46
  const { yStart, yEnd, xStart, xEnd } = coordinates;
42
47
 
@@ -74,10 +79,21 @@ const ColumnChartContent = ({
74
79
  seriesLabels={seriesLabels}
75
80
  xIndex={xIdx}
76
81
  onBarPress={onBarPress}
82
+ colorScale={colorScale}
77
83
  />
78
84
  );
79
85
  });
80
- }, [xLabels, data, xStart, yStart, xEnd, yEnd, onBarPress, yAxisConfig]);
86
+ }, [
87
+ xLabels,
88
+ data,
89
+ xStart,
90
+ yStart,
91
+ xEnd,
92
+ yEnd,
93
+ onBarPress,
94
+ yAxisConfig,
95
+ colorScale,
96
+ ]);
81
97
 
82
98
  return <G testID="column-chart-content">{columns}</G>;
83
99
  };
@@ -56,7 +56,7 @@ const Segment = ({
56
56
  height={adjustedHeight}
57
57
  rx={width / 2}
58
58
  fill={color}
59
- accessibilityLabel={`Column segment: value ${value}, x-label ${xLabel}, series ${seriesLabel}`}
59
+ accessibilityLabel={`Column segment: value ${value}, x-label ${xLabel}, series ${seriesLabel}, color ${color}`}
60
60
  testID={testID}
61
61
  onPress={onPress}
62
62
  />