@automattic/charts 1.3.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/dist/index.cjs +18 -114
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +0 -9
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +11 -10
- package/dist/index.d.ts +11 -10
- package/dist/index.js +27 -123
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/src/hooks/index.ts +0 -1
- package/src/hooks/test/use-chart-margin.test.tsx +21 -0
- package/src/hooks/use-chart-margin.tsx +4 -0
- package/src/providers/chart-context/global-charts-provider.tsx +1 -18
- package/src/style.css +10 -0
- package/src/types.ts +10 -0
- package/tsup.config.ts +3 -2
- package/src/hooks/test/use-tooltip-portal-relocator.test.ts +0 -216
- package/src/hooks/use-tooltip-portal-relocator.module.scss +0 -7
- package/src/hooks/use-tooltip-portal-relocator.ts +0 -188
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.4.0] - 2026-05-14
|
|
9
|
+
### Changed
|
|
10
|
+
- Charts: expose a source-side `./style.css` alias so monorepo consumers can resolve the import without a prior build. [#48682]
|
|
11
|
+
- Charts: expose tickValues on AxisOptions and nice on ScaleOptions so callers can force exact axis ticks. [#48722]
|
|
12
|
+
- Update package dependencies. [#48695]
|
|
13
|
+
- Update package dependencies. [#48696]
|
|
14
|
+
|
|
15
|
+
### Removed
|
|
16
|
+
- Charts: remove the `useTooltipPortalRelocator` hook and the `portalContainer` prop on `GlobalChartsProvider`. The relocator (added in #47118 / 0.56.4) caused tooltip glyphs and the tooltip box to drift away from the chart line by exactly the page scroll offset on scrolled pages. [#48617]
|
|
17
|
+
|
|
8
18
|
## [1.3.1] - 2026-05-11
|
|
9
19
|
### Changed
|
|
10
20
|
- Update dependencies. [#43811]
|
|
@@ -820,6 +830,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
820
830
|
- Fixed lints following ESLint rule changes for TS [#40584]
|
|
821
831
|
- Fixing a bug in Chart storybook data. [#40640]
|
|
822
832
|
|
|
833
|
+
[1.4.0]: https://github.com/Automattic/charts/compare/v1.3.1...v1.4.0
|
|
823
834
|
[1.3.1]: https://github.com/Automattic/charts/compare/v1.3.0...v1.3.1
|
|
824
835
|
[1.3.0]: https://github.com/Automattic/charts/compare/v1.2.1...v1.3.0
|
|
825
836
|
[1.2.1]: https://github.com/Automattic/charts/compare/v1.2.0...v1.2.1
|
package/dist/index.cjs
CHANGED
|
@@ -495,103 +495,6 @@ var useSingleChartContext = useChartInstanceContext;
|
|
|
495
495
|
var _d3color = require('@visx/vendor/d3-color');
|
|
496
496
|
|
|
497
497
|
|
|
498
|
-
// src/hooks/use-tooltip-portal-relocator.ts
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
// src/hooks/use-tooltip-portal-relocator.module.scss
|
|
502
|
-
var use_tooltip_portal_relocator_module_default = {
|
|
503
|
-
"relocatedPortal": "a8ccharts-jCw5dQ"
|
|
504
|
-
};
|
|
505
|
-
|
|
506
|
-
// src/hooks/use-tooltip-portal-relocator.ts
|
|
507
|
-
function isVisxPortalNode(node2) {
|
|
508
|
-
return node2 instanceof HTMLDivElement && node2.parentElement === document.body && !node2.id && !node2.className && node2.querySelector(".visx-tooltip") !== null;
|
|
509
|
-
}
|
|
510
|
-
var patchRefCount = 0;
|
|
511
|
-
var origRemoveChild = null;
|
|
512
|
-
var patchedRemoveChild = null;
|
|
513
|
-
var relocatedNodes = /* @__PURE__ */ new WeakSet();
|
|
514
|
-
function installRemoveChildPatch() {
|
|
515
|
-
if (patchRefCount++ > 0) {
|
|
516
|
-
return;
|
|
517
|
-
}
|
|
518
|
-
origRemoveChild = document.body.removeChild;
|
|
519
|
-
patchedRemoveChild = function(child) {
|
|
520
|
-
if (relocatedNodes.has(child) && child.parentNode !== this) {
|
|
521
|
-
relocatedNodes.delete(child);
|
|
522
|
-
_optionalChain([child, 'access', _2 => _2.parentNode, 'optionalAccess', _3 => _3.removeChild, 'call', _4 => _4(child)]);
|
|
523
|
-
return child;
|
|
524
|
-
}
|
|
525
|
-
return origRemoveChild.call(this, child);
|
|
526
|
-
};
|
|
527
|
-
document.body.removeChild = patchedRemoveChild;
|
|
528
|
-
}
|
|
529
|
-
function uninstallRemoveChildPatch() {
|
|
530
|
-
if (--patchRefCount > 0) {
|
|
531
|
-
return;
|
|
532
|
-
}
|
|
533
|
-
if (document.body.removeChild === patchedRemoveChild) {
|
|
534
|
-
document.body.removeChild = origRemoveChild;
|
|
535
|
-
}
|
|
536
|
-
origRemoveChild = null;
|
|
537
|
-
patchedRemoveChild = null;
|
|
538
|
-
}
|
|
539
|
-
function useTooltipPortalRelocator(containerRef) {
|
|
540
|
-
_react.useEffect.call(void 0, () => {
|
|
541
|
-
const container = _optionalChain([containerRef, 'optionalAccess', _5 => _5.current]);
|
|
542
|
-
if (!container) {
|
|
543
|
-
return;
|
|
544
|
-
}
|
|
545
|
-
const instanceNodes = /* @__PURE__ */ new Set();
|
|
546
|
-
const relocateNode = (node2) => {
|
|
547
|
-
if (!isVisxPortalNode(node2)) {
|
|
548
|
-
return;
|
|
549
|
-
}
|
|
550
|
-
node2.style.opacity = "0";
|
|
551
|
-
node2.classList.add(use_tooltip_portal_relocator_module_default.relocatedPortal);
|
|
552
|
-
const { activeElement } = node2.ownerDocument;
|
|
553
|
-
const focusedElement = activeElement instanceof HTMLElement && node2.contains(activeElement) ? activeElement : null;
|
|
554
|
-
container.insertBefore(node2, container.firstChild);
|
|
555
|
-
relocatedNodes.add(node2);
|
|
556
|
-
instanceNodes.add(node2);
|
|
557
|
-
if (focusedElement) {
|
|
558
|
-
focusedElement.focus();
|
|
559
|
-
}
|
|
560
|
-
requestAnimationFrame(() => {
|
|
561
|
-
requestAnimationFrame(() => {
|
|
562
|
-
node2.style.opacity = "";
|
|
563
|
-
});
|
|
564
|
-
});
|
|
565
|
-
};
|
|
566
|
-
installRemoveChildPatch();
|
|
567
|
-
for (const child of Array.from(document.body.children)) {
|
|
568
|
-
relocateNode(child);
|
|
569
|
-
}
|
|
570
|
-
const observer = new MutationObserver((mutations) => {
|
|
571
|
-
for (const mutation of mutations) {
|
|
572
|
-
for (const node2 of mutation.addedNodes) {
|
|
573
|
-
relocateNode(node2);
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
});
|
|
577
|
-
observer.observe(document.body, { childList: true });
|
|
578
|
-
return () => {
|
|
579
|
-
observer.disconnect();
|
|
580
|
-
for (const node2 of instanceNodes) {
|
|
581
|
-
if (node2 instanceof HTMLElement) {
|
|
582
|
-
node2.classList.remove(use_tooltip_portal_relocator_module_default.relocatedPortal);
|
|
583
|
-
}
|
|
584
|
-
if (node2.parentNode === container) {
|
|
585
|
-
document.body.appendChild(node2);
|
|
586
|
-
}
|
|
587
|
-
relocatedNodes.delete(node2);
|
|
588
|
-
}
|
|
589
|
-
instanceNodes.clear();
|
|
590
|
-
uninstallRemoveChildPatch();
|
|
591
|
-
};
|
|
592
|
-
}, [containerRef]);
|
|
593
|
-
}
|
|
594
|
-
|
|
595
498
|
// src/utils/create-composition.ts
|
|
596
499
|
function attachSubComponents(Chart2, subComponents) {
|
|
597
500
|
return Object.assign(Chart2, subComponents);
|
|
@@ -722,14 +625,14 @@ var getLongestTickWidth = (ticks, formatTick, labelStyle) => {
|
|
|
722
625
|
|
|
723
626
|
// src/utils/get-styles.ts
|
|
724
627
|
function getSeriesLineStyles(seriesData, index, providerTheme) {
|
|
725
|
-
const themeSemanticLineStyle = _optionalChain([providerTheme, 'optionalAccess',
|
|
726
|
-
const themeSeriesLineStyle = _optionalChain([providerTheme, 'optionalAccess',
|
|
727
|
-
return _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_optionalChain([seriesData, 'access',
|
|
628
|
+
const themeSemanticLineStyle = _optionalChain([providerTheme, 'optionalAccess', _2 => _2.lineChart, 'optionalAccess', _3 => _3.lineStyles, 'optionalAccess', _4 => _4[_optionalChain([seriesData, 'access', _5 => _5.options, 'optionalAccess', _6 => _6.type])]]);
|
|
629
|
+
const themeSeriesLineStyle = _optionalChain([providerTheme, 'optionalAccess', _7 => _7.seriesLineStyles, 'optionalAccess', _8 => _8[index % providerTheme.seriesLineStyles.length]]);
|
|
630
|
+
return _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_optionalChain([seriesData, 'access', _9 => _9.options, 'optionalAccess', _10 => _10.seriesLineStyle]), () => ( themeSemanticLineStyle)), () => ( themeSeriesLineStyle)), () => ( {}));
|
|
728
631
|
}
|
|
729
632
|
function getItemShapeStyles(series, index, theme, legendShape) {
|
|
730
|
-
const seriesShapeStyles = _nullishCoalesce(_optionalChain([series, 'access',
|
|
633
|
+
const seriesShapeStyles = _nullishCoalesce(_optionalChain([series, 'access', _11 => _11.options, 'optionalAccess', _12 => _12.legendShapeStyle]), () => ( {}));
|
|
731
634
|
const lineStyles = legendShape === "line" ? getSeriesLineStyles(series, index, theme) : {};
|
|
732
|
-
const themeShapeStyles = _optionalChain([theme, 'access',
|
|
635
|
+
const themeShapeStyles = _optionalChain([theme, 'access', _13 => _13.legend, 'optionalAccess', _14 => _14.shapeStyles, 'optionalAccess', _15 => _15[index]]);
|
|
733
636
|
const itemShapeStyles = {
|
|
734
637
|
...seriesShapeStyles,
|
|
735
638
|
...lineStyles
|
|
@@ -1096,13 +999,11 @@ var _jsxruntime = require('react/jsx-runtime');
|
|
|
1096
999
|
var GlobalChartsContext = /* @__PURE__ */ _react.createContext.call(void 0, null);
|
|
1097
1000
|
var GlobalChartsProvider = ({
|
|
1098
1001
|
children,
|
|
1099
|
-
theme
|
|
1100
|
-
portalContainer
|
|
1002
|
+
theme
|
|
1101
1003
|
}) => {
|
|
1102
1004
|
const [charts, setCharts] = _react.useState.call(void 0, () => /* @__PURE__ */ new Map());
|
|
1103
1005
|
const [hiddenSeries, setHiddenSeries] = _react.useState.call(void 0, () => /* @__PURE__ */ new Map());
|
|
1104
1006
|
const wrapperRef = _react.useRef.call(void 0, null);
|
|
1105
|
-
useTooltipPortalRelocator(_nullishCoalesce(portalContainer, () => ( wrapperRef)));
|
|
1106
1007
|
const providerTheme = _react.useMemo.call(void 0, () => {
|
|
1107
1008
|
return theme ? mergeThemes(defaultTheme, theme) : defaultTheme;
|
|
1108
1009
|
}, [theme]);
|
|
@@ -1202,12 +1103,12 @@ var GlobalChartsProvider = ({
|
|
|
1202
1103
|
const isPointPercentageData = data && typeof data === "object" && "value" in data && typeof data.value === "number" && !("data" in data);
|
|
1203
1104
|
return {
|
|
1204
1105
|
color: resolveColor({
|
|
1205
|
-
group: _optionalChain([data, 'optionalAccess',
|
|
1106
|
+
group: _optionalChain([data, 'optionalAccess', _16 => _16.group]),
|
|
1206
1107
|
index,
|
|
1207
|
-
overrideColor: overrideColor || isSeriesData && _optionalChain([data, 'optionalAccess',
|
|
1108
|
+
overrideColor: overrideColor || isSeriesData && _optionalChain([data, 'optionalAccess', _17 => _17.options, 'optionalAccess', _18 => _18.stroke]) || isPointPercentageData && _optionalChain([data, 'optionalAccess', _19 => _19.color])
|
|
1208
1109
|
}),
|
|
1209
1110
|
lineStyles: isSeriesData ? getSeriesLineStyles(data, index, providerTheme) : {},
|
|
1210
|
-
glyph: _optionalChain([providerTheme, 'access',
|
|
1111
|
+
glyph: _optionalChain([providerTheme, 'access', _20 => _20.glyphs, 'optionalAccess', _21 => _21[index]]),
|
|
1211
1112
|
shapeStyles: isSeriesData ? getItemShapeStyles(data, index, providerTheme, legendShape) : {}
|
|
1212
1113
|
};
|
|
1213
1114
|
}, [providerTheme, resolveColor]);
|
|
@@ -1298,7 +1199,7 @@ var useDeepMemo = (value) => {
|
|
|
1298
1199
|
var useXYChartTheme = (data) => {
|
|
1299
1200
|
const theme = useGlobalChartsTheme();
|
|
1300
1201
|
return _react.useMemo.call(void 0, () => {
|
|
1301
|
-
const seriesColors = (_nullishCoalesce(data, () => ( []))).map((series) => _optionalChain([series, 'access',
|
|
1202
|
+
const seriesColors = (_nullishCoalesce(data, () => ( []))).map((series) => _optionalChain([series, 'access', _22 => _22.options, 'optionalAccess', _23 => _23.stroke])).filter((color) => Boolean(color));
|
|
1302
1203
|
return _xychart.buildChartTheme.call(void 0, {
|
|
1303
1204
|
...theme,
|
|
1304
1205
|
colors: [...seriesColors, ..._nullishCoalesce(theme.colors, () => ( []))]
|
|
@@ -1310,7 +1211,7 @@ var useXYChartTheme = (data) => {
|
|
|
1310
1211
|
|
|
1311
1212
|
var useChartDataTransform = (data) => {
|
|
1312
1213
|
return _react.useMemo.call(void 0, () => {
|
|
1313
|
-
const firstPoint = _optionalChain([data, 'optionalAccess',
|
|
1214
|
+
const firstPoint = _optionalChain([data, 'optionalAccess', _24 => _24[0], 'optionalAccess', _25 => _25.data, 'optionalAccess', _26 => _26[0]]);
|
|
1314
1215
|
const hasDateProperties = firstPoint && ("date" in firstPoint || "dateString" in firstPoint);
|
|
1315
1216
|
if (!hasDateProperties) {
|
|
1316
1217
|
return data;
|
|
@@ -1348,9 +1249,9 @@ var DEFAULT_FONT_SIZE = 12;
|
|
|
1348
1249
|
var DEFAULT_TICK_LENGTH = 8;
|
|
1349
1250
|
var DEFAULT_Y_TICK_WIDTH = 40;
|
|
1350
1251
|
var getXAxisLabelMetrics = (theme, orientation) => {
|
|
1351
|
-
const xAxisStyles = orientation === "top" ? _optionalChain([theme, 'access',
|
|
1352
|
-
const fontSize = resolveFontSize(_optionalChain([xAxisStyles, 'optionalAccess',
|
|
1353
|
-
const tickLength = _nullishCoalesce(_optionalChain([xAxisStyles, 'optionalAccess',
|
|
1252
|
+
const xAxisStyles = orientation === "top" ? _optionalChain([theme, 'access', _27 => _27.axisStyles, 'optionalAccess', _28 => _28.x, 'optionalAccess', _29 => _29.top]) : _optionalChain([theme, 'access', _30 => _30.axisStyles, 'optionalAccess', _31 => _31.x, 'optionalAccess', _32 => _32.bottom]);
|
|
1253
|
+
const fontSize = resolveFontSize(_optionalChain([xAxisStyles, 'optionalAccess', _33 => _33.axisLabel, 'optionalAccess', _34 => _34.fontSize])) || resolveFontSize(_optionalChain([theme, 'access', _35 => _35.svgLabelSmall, 'optionalAccess', _36 => _36.fontSize])) || DEFAULT_FONT_SIZE;
|
|
1254
|
+
const tickLength = _nullishCoalesce(_optionalChain([xAxisStyles, 'optionalAccess', _37 => _37.tickLength]), () => ( DEFAULT_TICK_LENGTH));
|
|
1354
1255
|
return {
|
|
1355
1256
|
fontSize,
|
|
1356
1257
|
tickLength
|
|
@@ -1360,7 +1261,10 @@ var useChartMargin = (height, options, data, theme, horizontal = false) => {
|
|
|
1360
1261
|
const yTicks = _react.useMemo.call(void 0, () => {
|
|
1361
1262
|
const allDataPoints = data.flatMap((series) => series.data);
|
|
1362
1263
|
if (horizontal) {
|
|
1363
|
-
return allDataPoints.map((d) => d.label || _optionalChain([options, 'access',
|
|
1264
|
+
return allDataPoints.map((d) => d.label || _optionalChain([options, 'access', _38 => _38.axis, 'optionalAccess', _39 => _39.y, 'optionalAccess', _40 => _40.tickFormat, 'call', _41 => _41(d.date.getTime(), 0, [])]));
|
|
1265
|
+
}
|
|
1266
|
+
if (_optionalChain([options, 'access', _42 => _42.axis, 'optionalAccess', _43 => _43.y, 'optionalAccess', _44 => _44.tickValues, 'optionalAccess', _45 => _45.length])) {
|
|
1267
|
+
return options.axis.y.tickValues;
|
|
1364
1268
|
}
|
|
1365
1269
|
const minY = Math.min(...allDataPoints.map((d) => d.value));
|
|
1366
1270
|
const maxY = Math.max(...allDataPoints.map((d) => d.value));
|