@automattic/charts 4.1.1 → 4.2.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 +19 -0
- package/TOKENS.md +1 -1
- package/dist/index.cjs +875 -237
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +30 -1
- package/dist/index.d.cts +106 -6
- package/dist/index.d.ts +106 -6
- package/dist/index.js +875 -239
- package/dist/index.js.map +1 -1
- package/package.json +8 -8
- package/src/charts/area-chart/private/overlays.tsx +1 -2
- package/src/charts/bar-chart/bar-chart.tsx +67 -17
- package/src/charts/bar-chart/index.ts +1 -1
- package/src/charts/bar-chart/private/band-highlight.tsx +85 -0
- package/src/charts/bar-chart/private/band-scale.ts +13 -0
- package/src/charts/bar-chart/private/band-tooltip.tsx +138 -0
- package/src/charts/bar-chart/private/comparison-bars.tsx +5 -10
- package/src/charts/bar-chart/private/index.ts +2 -0
- package/src/charts/bar-chart/private/test/band-highlight.test.tsx +109 -0
- package/src/charts/bar-chart/private/test/band-tooltip.test.ts +26 -0
- package/src/charts/bar-chart/private/truncated-tick-component.tsx +1 -1
- package/src/charts/bar-chart/private/use-bar-chart-options.ts +1 -1
- package/src/charts/bar-chart/test/bar-chart-pointer-events.test.tsx +11 -23
- package/src/charts/bar-chart/test/bar-chart.test.tsx +565 -1
- package/src/charts/bar-list-chart/bar-list-chart.tsx +5 -3
- package/src/charts/conversion-funnel-chart/conversion-funnel-chart.tsx +1 -1
- package/src/charts/conversion-funnel-chart/types.ts +4 -2
- package/src/charts/geo-chart/types.ts +4 -2
- package/src/charts/heatmap-chart/build-calendar-data.ts +5 -11
- package/src/charts/heatmap-chart/build-month-calendar-data.ts +124 -0
- package/src/charts/heatmap-chart/heatmap-chart.module.scss +32 -0
- package/src/charts/heatmap-chart/heatmap-chart.tsx +191 -114
- package/src/charts/heatmap-chart/index.ts +6 -0
- package/src/charts/heatmap-chart/private/civil-day.ts +26 -0
- package/src/charts/heatmap-chart/private/column-groups.ts +71 -0
- package/src/charts/heatmap-chart/private/heatmap-legend.tsx +19 -3
- package/src/charts/heatmap-chart/private/index.ts +2 -0
- package/src/charts/heatmap-chart/private/keyboard-navigation.ts +201 -0
- package/src/charts/heatmap-chart/test/build-calendar-data.test.ts +36 -0
- package/src/charts/heatmap-chart/test/build-month-calendar-data.test.ts +194 -0
- package/src/charts/heatmap-chart/test/column-groups.test.ts +83 -0
- package/src/charts/heatmap-chart/test/heatmap-chart.test.tsx +428 -2
- package/src/charts/heatmap-chart/test/keyboard-navigation.test.ts +25 -0
- package/src/charts/heatmap-chart/test/use-month-calendar-heatmap-data.test.tsx +90 -0
- package/src/charts/heatmap-chart/test/zoned-month-calendar-data.test.ts +23 -0
- package/src/charts/heatmap-chart/types.ts +59 -3
- package/src/charts/heatmap-chart/use-month-calendar-heatmap-data.ts +34 -0
- package/src/charts/leaderboard-chart/types.ts +13 -14
- package/src/charts/line-chart/line-chart.tsx +1 -1
- package/src/charts/line-chart/private/line-chart-annotation.tsx +1 -1
- package/src/charts/line-chart/types.ts +2 -2
- package/src/charts/private/time-axis-options.ts +1 -1
- package/src/charts/private/with-responsive/with-responsive.tsx +2 -2
- package/src/charts/private/x-zoom/test/x-zoom.test.tsx +1 -3
- package/src/charts/private/x-zoom/x-zoom.tsx +1 -2
- package/src/components/legend/private/base-legend.tsx +1 -1
- package/src/components/tooltip/accessible-tooltip.tsx +127 -40
- package/src/components/tooltip/base-tooltip.module.scss +6 -1
- package/src/components/tooltip/private/bounded-tooltip.tsx +12 -6
- package/src/components/tooltip/test/accessible-tooltip.test.tsx +128 -0
- package/src/components/tooltip/test/bounded-tooltip.test.tsx +17 -0
- package/src/components/tooltip/test/xy-chart-tooltip.test.tsx +7 -0
- package/src/components/tooltip/xy-chart-tooltip.tsx +9 -10
- package/src/hooks/test/use-element-size.test.tsx +13 -13
- package/src/hooks/use-xychart-theme.ts +1 -1
- package/src/index.ts +7 -1
- package/src/providers/chart-context/themes.ts +1 -0
- package/src/styles/test/chart-scope.test.ts +1 -1
- package/src/types.ts +6 -13
- package/src/utils/format-metric-value.ts +4 -4
- package/src/utils/get-edge-tick-widths.ts +1 -1
- package/src/utils/get-styles.ts +1 -1
- package/src/visx/types.ts +7 -10
package/dist/index.cjs
CHANGED
|
@@ -983,7 +983,8 @@ const defaultTheme = {
|
|
|
983
983
|
},
|
|
984
984
|
heatmapChart: {
|
|
985
985
|
compactCellGap: 2,
|
|
986
|
-
compactCellSize: 11
|
|
986
|
+
compactCellSize: 11,
|
|
987
|
+
groupGap: 24
|
|
987
988
|
}
|
|
988
989
|
};
|
|
989
990
|
//#endregion
|
|
@@ -2183,7 +2184,10 @@ function useChartLegendItems(data, options = {}, legendShape) {
|
|
|
2183
2184
|
}
|
|
2184
2185
|
//#endregion
|
|
2185
2186
|
//#region src/components/tooltip/base-tooltip.module.scss
|
|
2186
|
-
var base_tooltip_module_default = {
|
|
2187
|
+
var base_tooltip_module_default = {
|
|
2188
|
+
"surface": "a8ccharts--zY0xG-surface",
|
|
2189
|
+
"tooltip": "a8ccharts--zY0xG-tooltip"
|
|
2190
|
+
};
|
|
2187
2191
|
//#endregion
|
|
2188
2192
|
//#region src/components/tooltip/base-tooltip.tsx
|
|
2189
2193
|
const DefaultTooltipContent = ({ data }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
@@ -2233,7 +2237,8 @@ const findClippingAncestor = (wrapper) => {
|
|
|
2233
2237
|
/**
|
|
2234
2238
|
* Where the box goes, in wrapper coordinates. Automatic placement flips to
|
|
2235
2239
|
* the side that clips less, then clamps inside `bounds`; below-axis placement
|
|
2236
|
-
* is centered on the anchor and clamped horizontally
|
|
2240
|
+
* is centered on the anchor and clamped horizontally; beside placement preserves
|
|
2241
|
+
* the anchor's y and only flips horizontally before bounds clamping.
|
|
2237
2242
|
*
|
|
2238
2243
|
* The flip measures against the visible part of the wrapper, its intersection
|
|
2239
2244
|
* with `bounds`. Only the clamp is bound by the page: a box that fits inside the
|
|
@@ -2247,7 +2252,7 @@ const findClippingAncestor = (wrapper) => {
|
|
|
2247
2252
|
* @param params.offsetTop - Gap between the anchor and the box, vertically.
|
|
2248
2253
|
* @param params.box - Rendered size of the box.
|
|
2249
2254
|
* @param params.wrapper - The wrapper's own edges, in wrapper coordinates.
|
|
2250
|
-
* @param params.placement -
|
|
2255
|
+
* @param params.placement - Below-axis, beside without vertical flipping, or automatic flipping.
|
|
2251
2256
|
* @param params.bounds - Edges the box must keep inside, in wrapper coordinates.
|
|
2252
2257
|
* @return The box's top-left corner; fixed placement preserves the axis's subpixel y.
|
|
2253
2258
|
*/
|
|
@@ -2271,7 +2276,8 @@ const getBoundedPosition = ({ left, top, offsetLeft, offsetTop, box, wrapper, bo
|
|
|
2271
2276
|
const upY = top - offsetTop - box.height;
|
|
2272
2277
|
const downOverflow = downY + box.height - fit.bottom;
|
|
2273
2278
|
const upOverflow = fit.top - upY;
|
|
2274
|
-
let y =
|
|
2279
|
+
let y = top;
|
|
2280
|
+
if (placement !== "beside") y = downOverflow > 0 && downOverflow > upOverflow ? upY : downY;
|
|
2275
2281
|
x = clamp(x, bounds.left, bounds.right, box.width);
|
|
2276
2282
|
y = clamp(y, bounds.top, bounds.bottom, box.height);
|
|
2277
2283
|
return {
|
|
@@ -2287,8 +2293,7 @@ const getBoundedPosition = ({ left, top, offsetLeft, offsetTop, box, wrapper, bo
|
|
|
2287
2293
|
* alone would let the box spill into an `overflow: hidden` card and be cut off.
|
|
2288
2294
|
*
|
|
2289
2295
|
* Re-measures on every render, so a box whose content changes width between
|
|
2290
|
-
* two hovers is placed for its current size.
|
|
2291
|
-
* below-axis exception.
|
|
2296
|
+
* two hovers is placed for its current size.
|
|
2292
2297
|
*
|
|
2293
2298
|
* @param props - visx `Tooltip` props.
|
|
2294
2299
|
* @param props.left - Anchor x, in wrapper coordinates.
|
|
@@ -2298,7 +2303,7 @@ const getBoundedPosition = ({ left, top, offsetLeft, offsetTop, box, wrapper, bo
|
|
|
2298
2303
|
* @param props.style - Box styles; visx's defaults unless `unstyled`.
|
|
2299
2304
|
* @param props.unstyled - Skip `style` and leave the box bare.
|
|
2300
2305
|
* @param props.children - Box content.
|
|
2301
|
-
* @param props.placement -
|
|
2306
|
+
* @param props.placement - Below-axis, beside without vertical flipping, or automatic flipping.
|
|
2302
2307
|
* @return The tooltip box.
|
|
2303
2308
|
*/
|
|
2304
2309
|
const BoundedTooltip = ({ left = 0, top = 0, offsetLeft = DEFAULT_OFFSET, offsetTop = DEFAULT_OFFSET, style = _visx_tooltip.defaultStyles, unstyled = false, children, placement = "auto", ...rest }) => {
|
|
@@ -2401,7 +2406,6 @@ const crosshairPaintProps = (props = {}) => {
|
|
|
2401
2406
|
};
|
|
2402
2407
|
const DEFAULT_GLYPH_RADIUS = 4;
|
|
2403
2408
|
const FALLBACK_COLOR = "#222";
|
|
2404
|
-
const DEFAULT_TOOLTIP_Z_INDEX = 3;
|
|
2405
2409
|
const PORTAL_OPTIONS = /* @__PURE__ */ new Set([
|
|
2406
2410
|
"scroll",
|
|
2407
2411
|
"debounce",
|
|
@@ -2429,7 +2433,7 @@ const defaultRenderGlyph$1 = ({ key, ...props }) => /* @__PURE__ */ (0, react_js
|
|
|
2429
2433
|
seriesKey: key,
|
|
2430
2434
|
...props
|
|
2431
2435
|
}, key);
|
|
2432
|
-
const XyChartTooltipContent = ({ tooltipContext, container, renderTooltip, renderGlyph = defaultRenderGlyph$1, glyphStyle, snapTooltipToDatumX = false, snapTooltipToDatumY = false, showVerticalCrosshair = false, showHorizontalCrosshair = false, showDatumGlyph = false, showSeriesGlyphs = false, verticalCrosshairStyle, horizontalCrosshairStyle, detectBounds = true, tooltipPlacement = "auto", zIndex =
|
|
2436
|
+
const XyChartTooltipContent = ({ tooltipContext, container, renderTooltip, renderGlyph = defaultRenderGlyph$1, glyphStyle, snapTooltipToDatumX = false, snapTooltipToDatumY = false, showVerticalCrosshair = false, showHorizontalCrosshair = false, showDatumGlyph = false, showSeriesGlyphs = false, verticalCrosshairStyle, horizontalCrosshairStyle, detectBounds = true, tooltipPlacement = "auto", tooltipAnchorTop, zIndex = 3, style, ...rest }) => {
|
|
2433
2437
|
const tooltipProps = Object.fromEntries(Object.entries(rest).filter(([key]) => !PORTAL_OPTIONS.has(key)));
|
|
2434
2438
|
const { colorScale, theme, innerHeight = 0, innerWidth = 0, margin, xScale, yScale, dataRegistry } = (0, react.useContext)(_visx_xychart.DataContext) || {};
|
|
2435
2439
|
const tooltipContent = renderTooltip ? renderTooltip({
|
|
@@ -2484,7 +2488,7 @@ const XyChartTooltipContent = ({ tooltipContext, container, renderTooltip, rende
|
|
|
2484
2488
|
const crosshairStroke = theme?.gridStyles?.stroke ?? theme?.htmlLabel?.color ?? FALLBACK_COLOR;
|
|
2485
2489
|
const marginTop = margin?.top ?? 0;
|
|
2486
2490
|
const marginLeft = margin?.left ?? 0;
|
|
2487
|
-
const TooltipComponent = detectBounds || tooltipPlacement
|
|
2491
|
+
const TooltipComponent = detectBounds || tooltipPlacement !== "auto" ? BoundedTooltip : _visx_tooltip.Tooltip;
|
|
2488
2492
|
const boxStyle = {
|
|
2489
2493
|
..._visx_tooltip.defaultStyles,
|
|
2490
2494
|
zIndex,
|
|
@@ -2521,11 +2525,11 @@ const XyChartTooltipContent = ({ tooltipContext, container, renderTooltip, rende
|
|
|
2521
2525
|
]
|
|
2522
2526
|
}), container && (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TooltipComponent, {
|
|
2523
2527
|
left: tooltipLeft,
|
|
2524
|
-
top: tooltipPlacement === "below-axis" ? marginTop + innerHeight + (margin?.bottom ?? 0) : tooltipTop,
|
|
2528
|
+
top: tooltipPlacement === "below-axis" ? marginTop + innerHeight + (margin?.bottom ?? 0) : tooltipAnchorTop ?? tooltipTop,
|
|
2525
2529
|
style: boxStyle,
|
|
2526
2530
|
applyPositionStyle: true,
|
|
2527
2531
|
...tooltipProps,
|
|
2528
|
-
...tooltipPlacement
|
|
2532
|
+
...tooltipPlacement !== "auto" && { placement: tooltipPlacement },
|
|
2529
2533
|
children: tooltipContent
|
|
2530
2534
|
}), container)] });
|
|
2531
2535
|
};
|
|
@@ -2591,11 +2595,32 @@ const AccessibleTooltip = ({ renderTooltip, selectedIndex, tooltipRef, keyboardF
|
|
|
2591
2595
|
return flattened;
|
|
2592
2596
|
}, [series, mode]);
|
|
2593
2597
|
const hasKeyboardSelection = (0, react.useRef)(false);
|
|
2598
|
+
const closeTooltipNow = (0, react.useCallback)(() => {
|
|
2599
|
+
tooltipContext?.updateTooltip({
|
|
2600
|
+
tooltipOpen: false,
|
|
2601
|
+
tooltipLeft: void 0,
|
|
2602
|
+
tooltipTop: void 0,
|
|
2603
|
+
tooltipData: void 0
|
|
2604
|
+
});
|
|
2605
|
+
}, []);
|
|
2606
|
+
const chartId = (0, react.useContext)(ChartInstanceContext)?.chartId;
|
|
2607
|
+
const { getHiddenSeries } = useGlobalChartsContext();
|
|
2608
|
+
const hiddenSeriesKey = chartId ? JSON.stringify([...getHiddenSeries(chartId)].sort()) : void 0;
|
|
2609
|
+
const lastHiddenSeriesKey = (0, react.useRef)(hiddenSeriesKey);
|
|
2610
|
+
(0, react.useEffect)(() => {
|
|
2611
|
+
const changed = lastHiddenSeriesKey.current !== hiddenSeriesKey;
|
|
2612
|
+
lastHiddenSeriesKey.current = hiddenSeriesKey;
|
|
2613
|
+
if (changed && selectedIndex === void 0) closeTooltipNow();
|
|
2614
|
+
}, [
|
|
2615
|
+
hiddenSeriesKey,
|
|
2616
|
+
selectedIndex,
|
|
2617
|
+
closeTooltipNow
|
|
2618
|
+
]);
|
|
2594
2619
|
(0, react.useEffect)(() => {
|
|
2595
2620
|
if (selectedIndex === void 0) {
|
|
2596
2621
|
if (hasKeyboardSelection.current) {
|
|
2597
2622
|
hasKeyboardSelection.current = false;
|
|
2598
|
-
|
|
2623
|
+
closeTooltipNow();
|
|
2599
2624
|
}
|
|
2600
2625
|
return;
|
|
2601
2626
|
}
|
|
@@ -2664,14 +2689,43 @@ const AccessibleTooltip = ({ renderTooltip, selectedIndex, tooltipRef, keyboardF
|
|
|
2664
2689
|
renderTooltip: focusableRenderTooltip
|
|
2665
2690
|
});
|
|
2666
2691
|
};
|
|
2667
|
-
const useKeyboardNavigation = ({ selectedIndex, setSelectedIndex, isNavigating, setIsNavigating, chartRef, totalPoints, onActivate, preventTooltipScroll = false }) => {
|
|
2692
|
+
const useKeyboardNavigation = ({ selectedIndex, setSelectedIndex, isNavigating, setIsNavigating, chartRef, totalPoints, onActivate, preventTooltipScroll = false, visibleSeriesKey }) => {
|
|
2693
|
+
const getChartRoot = (0, react.useCallback)(() => chartRef.current?.closest("[role=\"grid\"]") ?? chartRef.current, [chartRef]);
|
|
2694
|
+
const focusWithoutScrollIfNeeded = (0, react.useCallback)((element) => {
|
|
2695
|
+
if (preventTooltipScroll) element?.focus({ preventScroll: true });
|
|
2696
|
+
else element?.focus();
|
|
2697
|
+
}, [preventTooltipScroll]);
|
|
2698
|
+
const tooltipRef = (0, react.useCallback)((element) => {
|
|
2699
|
+
if (element && selectedIndex !== void 0) focusWithoutScrollIfNeeded(element);
|
|
2700
|
+
}, [focusWithoutScrollIfNeeded, selectedIndex]);
|
|
2701
|
+
const previousTotalPoints = (0, react.useRef)(totalPoints);
|
|
2702
|
+
const previousVisibleSeriesKey = (0, react.useRef)(visibleSeriesKey);
|
|
2703
|
+
(0, react.useEffect)(() => {
|
|
2704
|
+
const countChanged = previousTotalPoints.current !== totalPoints;
|
|
2705
|
+
const seriesChanged = previousVisibleSeriesKey.current !== visibleSeriesKey;
|
|
2706
|
+
previousTotalPoints.current = totalPoints;
|
|
2707
|
+
previousVisibleSeriesKey.current = visibleSeriesKey;
|
|
2708
|
+
if (!countChanged && !seriesChanged || selectedIndex === void 0) return;
|
|
2709
|
+
const { activeElement } = document;
|
|
2710
|
+
const focusIsInChart = activeElement !== null && !!getChartRoot()?.contains(activeElement);
|
|
2711
|
+
if (totalPoints === 0 || !focusIsInChart || !countChanged) {
|
|
2712
|
+
setSelectedIndex(void 0);
|
|
2713
|
+
setIsNavigating(false);
|
|
2714
|
+
if (focusIsInChart) focusWithoutScrollIfNeeded(getChartRoot());
|
|
2715
|
+
return;
|
|
2716
|
+
}
|
|
2717
|
+
setSelectedIndex(Math.min(selectedIndex, totalPoints - 1));
|
|
2718
|
+
}, [
|
|
2719
|
+
selectedIndex,
|
|
2720
|
+
totalPoints,
|
|
2721
|
+
visibleSeriesKey,
|
|
2722
|
+
setSelectedIndex,
|
|
2723
|
+
setIsNavigating,
|
|
2724
|
+
getChartRoot,
|
|
2725
|
+
focusWithoutScrollIfNeeded
|
|
2726
|
+
]);
|
|
2668
2727
|
return {
|
|
2669
|
-
tooltipRef
|
|
2670
|
-
if (element && selectedIndex !== void 0) {
|
|
2671
|
-
if (preventTooltipScroll) element.focus({ preventScroll: true });
|
|
2672
|
-
else element.focus();
|
|
2673
|
-
}
|
|
2674
|
-
}, [preventTooltipScroll, selectedIndex]),
|
|
2728
|
+
tooltipRef,
|
|
2675
2729
|
onChartFocus: (0, react.useCallback)((event) => {
|
|
2676
2730
|
if (event.currentTarget.contains(event.relatedTarget)) return;
|
|
2677
2731
|
if (!isNavigating && selectedIndex !== void 0) setSelectedIndex(0);
|
|
@@ -2684,44 +2738,35 @@ const useKeyboardNavigation = ({ selectedIndex, setSelectedIndex, isNavigating,
|
|
|
2684
2738
|
setIsNavigating(false);
|
|
2685
2739
|
}, [setIsNavigating]),
|
|
2686
2740
|
onChartKeyDown: (0, react.useCallback)((event) => {
|
|
2687
|
-
if (
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
else chartRef.current?.focus();
|
|
2691
|
-
};
|
|
2692
|
-
if (event.key === "Tab") {
|
|
2693
|
-
focusChart();
|
|
2741
|
+
if (event.key === "Tab" || event.key === "Escape") {
|
|
2742
|
+
if (event.key === "Escape" && selectedIndex !== void 0) event.preventDefault();
|
|
2743
|
+
focusWithoutScrollIfNeeded(getChartRoot());
|
|
2694
2744
|
setSelectedIndex(void 0);
|
|
2695
2745
|
setIsNavigating(false);
|
|
2696
2746
|
return;
|
|
2697
2747
|
}
|
|
2748
|
+
if (totalPoints === 0) return;
|
|
2698
2749
|
const currentSelectedIndex = selectedIndex === void 0 ? -1 : selectedIndex;
|
|
2699
|
-
if (
|
|
2700
|
-
|
|
2701
|
-
setSelectedIndex(void 0);
|
|
2702
|
-
setIsNavigating(false);
|
|
2703
|
-
return;
|
|
2704
|
-
}
|
|
2705
|
-
event.preventDefault();
|
|
2706
|
-
if (["ArrowRight"].includes(event.key)) {
|
|
2750
|
+
if (event.key === "ArrowRight") {
|
|
2751
|
+
event.preventDefault();
|
|
2707
2752
|
setIsNavigating(true);
|
|
2708
|
-
setSelectedIndex((currentSelectedIndex + 1
|
|
2709
|
-
} else if (
|
|
2753
|
+
setSelectedIndex(Math.min(currentSelectedIndex + 1, totalPoints - 1));
|
|
2754
|
+
} else if (event.key === "ArrowLeft") {
|
|
2755
|
+
event.preventDefault();
|
|
2710
2756
|
setIsNavigating(true);
|
|
2711
|
-
setSelectedIndex((currentSelectedIndex - 1
|
|
2712
|
-
} else if (event.key === "
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
} else if ((event.key === "Enter" || event.key === " ") && selectedIndex !== void 0) onActivate?.(selectedIndex);
|
|
2757
|
+
setSelectedIndex(Math.max(currentSelectedIndex - 1, 0));
|
|
2758
|
+
} else if ((event.key === "Enter" || event.key === " ") && selectedIndex !== void 0) {
|
|
2759
|
+
event.preventDefault();
|
|
2760
|
+
onActivate?.(selectedIndex);
|
|
2761
|
+
}
|
|
2717
2762
|
}, [
|
|
2718
2763
|
totalPoints,
|
|
2719
2764
|
selectedIndex,
|
|
2720
2765
|
setSelectedIndex,
|
|
2721
2766
|
setIsNavigating,
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2767
|
+
getChartRoot,
|
|
2768
|
+
focusWithoutScrollIfNeeded,
|
|
2769
|
+
onActivate
|
|
2725
2770
|
])
|
|
2726
2771
|
};
|
|
2727
2772
|
};
|
|
@@ -5278,6 +5323,20 @@ function useBarChartOptions(data, horizontal, options = {}, isSeriesRendered = A
|
|
|
5278
5323
|
]);
|
|
5279
5324
|
}
|
|
5280
5325
|
//#endregion
|
|
5326
|
+
//#region src/charts/bar-chart/private/band-scale.ts
|
|
5327
|
+
/**
|
|
5328
|
+
* Match the inner slot scale used by visx BarGroup.
|
|
5329
|
+
* @param keys - Visible primary series keys.
|
|
5330
|
+
* @param bandwidth - Category band width.
|
|
5331
|
+
* @param padding - Padding between slots.
|
|
5332
|
+
* @return The grouped bar scale.
|
|
5333
|
+
*/
|
|
5334
|
+
const createGroupScale = (keys, bandwidth, padding) => (0, _visx_scale.scaleBand)({
|
|
5335
|
+
domain: keys,
|
|
5336
|
+
range: [0, bandwidth],
|
|
5337
|
+
padding
|
|
5338
|
+
});
|
|
5339
|
+
//#endregion
|
|
5281
5340
|
//#region src/charts/bar-chart/private/comparison-bars-geometry.ts
|
|
5282
5341
|
/**
|
|
5283
5342
|
* Output position of a value scale's baseline: zero if in-domain, else the
|
|
@@ -5350,11 +5409,7 @@ const ComparisonBars = ({ comparisonEntries, primaryKeys, groupPadding, horizont
|
|
|
5350
5409
|
const valueScale = horizontal ? xScale : yScale;
|
|
5351
5410
|
const bandwidth = bandScale.bandwidth ? bandScale.bandwidth() : 0;
|
|
5352
5411
|
if (!bandwidth) return null;
|
|
5353
|
-
const groupScale = (
|
|
5354
|
-
domain: primaryKeys,
|
|
5355
|
-
range: [0, bandwidth],
|
|
5356
|
-
padding: groupPadding
|
|
5357
|
-
});
|
|
5412
|
+
const groupScale = createGroupScale(primaryKeys, bandwidth, groupPadding);
|
|
5358
5413
|
const slotThickness = groupScale.bandwidth();
|
|
5359
5414
|
const baseline = getValueScaleBaseline(valueScale);
|
|
5360
5415
|
const bandAccessor = horizontal ? yAccessor : xAccessor;
|
|
@@ -5406,6 +5461,163 @@ const ComparisonBars = ({ comparisonEntries, primaryKeys, groupPadding, horizont
|
|
|
5406
5461
|
});
|
|
5407
5462
|
};
|
|
5408
5463
|
//#endregion
|
|
5464
|
+
//#region src/charts/bar-chart/private/band-highlight.tsx
|
|
5465
|
+
/**
|
|
5466
|
+
* Render and report the active band using the chart’s registered scales.
|
|
5467
|
+
* @param root0 - Highlight options.
|
|
5468
|
+
* @param root0.visible - Whether to paint the band.
|
|
5469
|
+
* @param root0.horizontal - Whether categories run vertically.
|
|
5470
|
+
* @param root0.onChange - Receives selected band geometry.
|
|
5471
|
+
* @return The optional band highlight.
|
|
5472
|
+
*/
|
|
5473
|
+
function BandHighlight({ visible, horizontal, onChange }) {
|
|
5474
|
+
const { xScale, yScale, dataRegistry, margin, innerWidth, innerHeight } = (0, react.useContext)(_visx_xychart.DataContext);
|
|
5475
|
+
const { tooltipOpen, tooltipData } = (0, react.useContext)(_visx_xychart.TooltipContext);
|
|
5476
|
+
const nearest = tooltipData?.nearestDatum;
|
|
5477
|
+
const selection = (0, react.useMemo)(() => {
|
|
5478
|
+
if (!tooltipOpen || !nearest) return null;
|
|
5479
|
+
const scale = horizontal ? yScale : xScale;
|
|
5480
|
+
const entry = dataRegistry?.get(nearest.key);
|
|
5481
|
+
const accessor = horizontal ? entry?.yAccessor : entry?.xAccessor;
|
|
5482
|
+
if (!scale?.bandwidth || !accessor) return null;
|
|
5483
|
+
const position = scale(accessor(nearest.datum));
|
|
5484
|
+
if (position === void 0 || !Number.isFinite(position)) return null;
|
|
5485
|
+
return {
|
|
5486
|
+
datum: nearest.datum,
|
|
5487
|
+
x: horizontal ? margin?.left ?? 0 : position,
|
|
5488
|
+
y: horizontal ? position : margin?.top ?? 0,
|
|
5489
|
+
width: horizontal ? innerWidth : scale.bandwidth(),
|
|
5490
|
+
height: horizontal ? scale.bandwidth() : innerHeight
|
|
5491
|
+
};
|
|
5492
|
+
}, [
|
|
5493
|
+
tooltipOpen,
|
|
5494
|
+
nearest,
|
|
5495
|
+
horizontal,
|
|
5496
|
+
xScale,
|
|
5497
|
+
yScale,
|
|
5498
|
+
dataRegistry,
|
|
5499
|
+
margin,
|
|
5500
|
+
innerWidth,
|
|
5501
|
+
innerHeight
|
|
5502
|
+
]);
|
|
5503
|
+
const stableSelection = useDeepMemo(selection);
|
|
5504
|
+
const onChangeRef = (0, react.useRef)(onChange);
|
|
5505
|
+
onChangeRef.current = onChange;
|
|
5506
|
+
(0, react.useEffect)(() => {
|
|
5507
|
+
onChangeRef.current?.(stableSelection);
|
|
5508
|
+
}, [stableSelection]);
|
|
5509
|
+
(0, react.useEffect)(() => () => onChangeRef.current?.(null), []);
|
|
5510
|
+
if (!visible || !selection) return null;
|
|
5511
|
+
const { x, y, width, height } = selection;
|
|
5512
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
|
|
5513
|
+
x,
|
|
5514
|
+
y,
|
|
5515
|
+
width,
|
|
5516
|
+
height,
|
|
5517
|
+
pointerEvents: "none",
|
|
5518
|
+
fill: CATALOG_POINTERS.surfaceSecondary
|
|
5519
|
+
});
|
|
5520
|
+
}
|
|
5521
|
+
//#endregion
|
|
5522
|
+
//#region src/charts/bar-chart/private/band-tooltip.tsx
|
|
5523
|
+
/**
|
|
5524
|
+
* Find a category by its painted center, including outer padding and reversed ranges.
|
|
5525
|
+
* @param data - Registered series points.
|
|
5526
|
+
* @param accessor - Category accessor.
|
|
5527
|
+
* @param scale - Rendered category band scale.
|
|
5528
|
+
* @param position - Pointer coordinate on the category axis.
|
|
5529
|
+
* @return Index of the nearest category, or -1 when none is registered.
|
|
5530
|
+
*/
|
|
5531
|
+
function nearestBandIndex(data, accessor, scale, position) {
|
|
5532
|
+
let nearest = -1;
|
|
5533
|
+
let distance = Infinity;
|
|
5534
|
+
data.forEach((datum, index) => {
|
|
5535
|
+
const start = scale(accessor(datum));
|
|
5536
|
+
if (start === void 0) return;
|
|
5537
|
+
const candidate = Math.abs(start + scale.bandwidth() / 2 - position);
|
|
5538
|
+
if (candidate < distance) {
|
|
5539
|
+
distance = candidate;
|
|
5540
|
+
nearest = index;
|
|
5541
|
+
}
|
|
5542
|
+
});
|
|
5543
|
+
return nearest;
|
|
5544
|
+
}
|
|
5545
|
+
/**
|
|
5546
|
+
* Correct visx's range-based band inversion, which omits outer padding.
|
|
5547
|
+
* @param root0 - Registered series selection.
|
|
5548
|
+
* @param root0.keys - Visible series keys.
|
|
5549
|
+
* @param root0.groupPadding - Padding between grouped bars.
|
|
5550
|
+
* @param root0.withTooltips - Whether pointer events update the tooltip.
|
|
5551
|
+
* @param root0.onPointerDown - Receives the corrected pointer-down datum.
|
|
5552
|
+
* @param root0.onPointerUp - Receives the corrected pointer-up datum.
|
|
5553
|
+
* @return No visual content.
|
|
5554
|
+
*/
|
|
5555
|
+
function BandTooltip({ keys, groupPadding, withTooltips, onPointerDown, onPointerUp }) {
|
|
5556
|
+
const { xScale, yScale, dataRegistry, horizontal } = (0, react.useContext)(_visx_xychart.DataContext);
|
|
5557
|
+
const { showTooltip } = (0, react.useContext)(_visx_xychart.TooltipContext);
|
|
5558
|
+
const scale = horizontal ? yScale : xScale;
|
|
5559
|
+
const bandwidth = scale?.bandwidth?.() ?? 0;
|
|
5560
|
+
const groupScale = (0, react.useMemo)(() => createGroupScale(keys, bandwidth, groupPadding), [
|
|
5561
|
+
keys,
|
|
5562
|
+
bandwidth,
|
|
5563
|
+
groupPadding
|
|
5564
|
+
]);
|
|
5565
|
+
const getSelections = (0, react.useCallback)((params) => {
|
|
5566
|
+
const point = params?.svgPoint;
|
|
5567
|
+
if (!point || !scale?.bandwidth) return [];
|
|
5568
|
+
const selections = [];
|
|
5569
|
+
for (const key of keys) {
|
|
5570
|
+
const entry = dataRegistry?.get(key);
|
|
5571
|
+
if (!entry) continue;
|
|
5572
|
+
const accessor = horizontal ? entry.yAccessor : entry.xAccessor;
|
|
5573
|
+
const index = nearestBandIndex(entry.data, accessor, scale, horizontal ? point.y : point.x);
|
|
5574
|
+
if (index < 0) continue;
|
|
5575
|
+
const datum = entry.data[index];
|
|
5576
|
+
const start = Number(scale(accessor(datum))) + Number(groupScale(key));
|
|
5577
|
+
const end = start + groupScale.step();
|
|
5578
|
+
const position = horizontal ? point.y : point.x;
|
|
5579
|
+
const distance = position >= start && position <= end ? 0 : Math.abs(position - (start + end) / 2);
|
|
5580
|
+
selections.push({
|
|
5581
|
+
event: params.event,
|
|
5582
|
+
key,
|
|
5583
|
+
datum,
|
|
5584
|
+
index,
|
|
5585
|
+
svgPoint: point,
|
|
5586
|
+
distanceX: horizontal ? 0 : distance,
|
|
5587
|
+
distanceY: horizontal ? distance : 0
|
|
5588
|
+
});
|
|
5589
|
+
}
|
|
5590
|
+
return selections;
|
|
5591
|
+
}, [
|
|
5592
|
+
scale,
|
|
5593
|
+
dataRegistry,
|
|
5594
|
+
horizontal,
|
|
5595
|
+
keys,
|
|
5596
|
+
groupScale
|
|
5597
|
+
]);
|
|
5598
|
+
const handlePointer = (0, react.useCallback)((params) => {
|
|
5599
|
+
const selections = getSelections(params);
|
|
5600
|
+
if (withTooltips && params?.event.type !== "pointerup") selections.forEach(showTooltip);
|
|
5601
|
+
const callback = params?.event.type === "pointerdown" ? onPointerDown : onPointerUp;
|
|
5602
|
+
if (params?.event.type === "pointermove" || !callback) return;
|
|
5603
|
+
const nearest = selections.reduce((best, selection) => {
|
|
5604
|
+
const distance = (value) => Math.hypot(value.distanceX, value.distanceY);
|
|
5605
|
+
return !best || distance(selection) <= distance(best) ? selection : best;
|
|
5606
|
+
}, void 0);
|
|
5607
|
+
if (nearest) callback(nearest);
|
|
5608
|
+
}, [
|
|
5609
|
+
getSelections,
|
|
5610
|
+
withTooltips,
|
|
5611
|
+
showTooltip,
|
|
5612
|
+
onPointerDown,
|
|
5613
|
+
onPointerUp
|
|
5614
|
+
]);
|
|
5615
|
+
(0, _visx_xychart.useEventEmitter)("pointermove", withTooltips ? handlePointer : void 0);
|
|
5616
|
+
(0, _visx_xychart.useEventEmitter)("pointerdown", handlePointer);
|
|
5617
|
+
(0, _visx_xychart.useEventEmitter)("pointerup", onPointerUp ? handlePointer : void 0);
|
|
5618
|
+
return null;
|
|
5619
|
+
}
|
|
5620
|
+
//#endregion
|
|
5409
5621
|
//#region src/charts/bar-chart/bar-chart.tsx
|
|
5410
5622
|
const validateData$2 = (data) => {
|
|
5411
5623
|
if (!data?.length) return "No data available";
|
|
@@ -5417,7 +5629,7 @@ const renderTooltipRow = (label, value) => /* @__PURE__ */ (0, react_jsx_runtime
|
|
|
5417
5629
|
className: bar_chart_module_default["bar-chart__tooltip-row"],
|
|
5418
5630
|
children: (0, _wordpress_i18n.sprintf)((0, _wordpress_i18n.__)("%1$s: %2$s", "jetpack-charts"), label, value)
|
|
5419
5631
|
});
|
|
5420
|
-
const BarChartInternal = ({ data, chartId: providedChartId, width, height, className, margin, withTooltips = false, showLegend = false, legend = {}, gridVisibility: gridVisibilityProp, renderTooltip, options = {}, orientation = "vertical", withPatterns = false, showZeroValues = false, defaultHiddenSeries, animation, children, gap = "md", onPointerDown, onPointerUp, onDatumActivate }) => {
|
|
5632
|
+
const BarChartInternal = ({ data, chartId: providedChartId, width, height, className, margin, withTooltips = false, showLegend = false, legend = {}, gridVisibility: gridVisibilityProp, renderTooltip, tooltipPlacement, tooltipAnchorTop, options = {}, orientation = "vertical", withPatterns = false, showZeroValues = false, withBandHighlight = false, onBandHighlightChange, defaultHiddenSeries, animation, children, gap = "md", onPointerDown, onPointerUp, onDatumActivate }) => {
|
|
5421
5633
|
const legendInteractive = legend.interactive ?? false;
|
|
5422
5634
|
const legendCollapseGroups = legend.collapseGroups ?? false;
|
|
5423
5635
|
const horizontal = orientation === "horizontal";
|
|
@@ -5443,8 +5655,6 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height, class
|
|
|
5443
5655
|
}, [height]);
|
|
5444
5656
|
const [selectedIndex, setSelectedIndex] = (0, react.useState)(void 0);
|
|
5445
5657
|
const [isNavigating, setIsNavigating] = (0, react.useState)(false);
|
|
5446
|
-
const primarySeriesForNav = dataWithVisibleZeros.filter((s) => s.options?.type !== "comparison");
|
|
5447
|
-
const totalPoints = Math.max(0, ...primarySeriesForNav.map((s) => s.data?.length || 0)) * primarySeriesForNav.length;
|
|
5448
5658
|
const seriesWithVisibility = (0, react.useMemo)(() => dataWithVisibleZeros.map((series, index) => ({
|
|
5449
5659
|
series,
|
|
5450
5660
|
index,
|
|
@@ -5454,6 +5664,7 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height, class
|
|
|
5454
5664
|
return seriesWithVisibility.every(({ isVisible }) => !isVisible);
|
|
5455
5665
|
}, [seriesWithVisibility]);
|
|
5456
5666
|
const primaryEntries = (0, react.useMemo)(() => seriesWithVisibility.filter(({ isVisible, series }) => isVisible && series.options?.type !== "comparison"), [seriesWithVisibility]);
|
|
5667
|
+
const totalPoints = Math.max(0, ...primaryEntries.map((e) => e.series.data.length)) * primaryEntries.length;
|
|
5457
5668
|
const primaryKeys = (0, react.useMemo)(() => primaryEntries.map(({ series }) => series.label), [primaryEntries]);
|
|
5458
5669
|
const primarySeries = (0, react.useMemo)(() => primaryEntries.map(({ series }) => series), [primaryEntries]);
|
|
5459
5670
|
const activateSelectedBar = (0, react.useCallback)((index) => {
|
|
@@ -5468,6 +5679,7 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height, class
|
|
|
5468
5679
|
key: series.label
|
|
5469
5680
|
});
|
|
5470
5681
|
}, [primaryEntries, onDatumActivate]);
|
|
5682
|
+
const visibleSeriesKey = (0, react.useMemo)(() => JSON.stringify(primaryKeys), [primaryKeys]);
|
|
5471
5683
|
const { tooltipRef, onChartFocus, onChartBlur, onChartKeyDown } = useKeyboardNavigation({
|
|
5472
5684
|
selectedIndex,
|
|
5473
5685
|
setSelectedIndex,
|
|
@@ -5475,7 +5687,8 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height, class
|
|
|
5475
5687
|
setIsNavigating,
|
|
5476
5688
|
chartRef,
|
|
5477
5689
|
totalPoints,
|
|
5478
|
-
onActivate: activateSelectedBar
|
|
5690
|
+
onActivate: activateSelectedBar,
|
|
5691
|
+
visibleSeriesKey
|
|
5479
5692
|
});
|
|
5480
5693
|
const comparisonEntries = (0, react.useMemo)(() => {
|
|
5481
5694
|
const primaryByGroup = new Map(primaryEntries.map(({ series, index }) => [series.group, {
|
|
@@ -5538,7 +5751,7 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height, class
|
|
|
5538
5751
|
chartOptions.yScale,
|
|
5539
5752
|
horizontal
|
|
5540
5753
|
]);
|
|
5541
|
-
const getBarBackground = (0, react.useCallback)((index) => () => withPatterns ? `url(#${getPatternId(chartId, index)})` : getElementStyles({
|
|
5754
|
+
const getBarBackground = (0, react.useCallback)((index) => (datum) => withPatterns ? `url(#${getPatternId(chartId, index)})` : datum.color ?? getElementStyles({
|
|
5542
5755
|
data: dataSorted[index],
|
|
5543
5756
|
index
|
|
5544
5757
|
}).color, [
|
|
@@ -5708,13 +5921,13 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height, class
|
|
|
5708
5921
|
const chartHeight = contentHeight > 0 ? contentHeight : height;
|
|
5709
5922
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5710
5923
|
role: "grid",
|
|
5924
|
+
ref: chartRef,
|
|
5711
5925
|
"aria-label": (0, _wordpress_i18n.__)("Bar chart", "jetpack-charts"),
|
|
5712
5926
|
tabIndex: 0,
|
|
5713
5927
|
onKeyDown: onChartKeyDown,
|
|
5714
5928
|
onFocus: onChartFocus,
|
|
5715
5929
|
onBlur: onChartBlur,
|
|
5716
5930
|
children: chartHeight > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5717
|
-
ref: chartRef,
|
|
5718
5931
|
className: xy_plot_module_default["xy-plot"],
|
|
5719
5932
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_visx_xychart.XYChart, {
|
|
5720
5933
|
theme,
|
|
@@ -5727,15 +5940,24 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height, class
|
|
|
5727
5940
|
xScale,
|
|
5728
5941
|
yScale,
|
|
5729
5942
|
horizontal,
|
|
5730
|
-
onPointerDown,
|
|
5731
|
-
onPointerUp,
|
|
5732
5943
|
pointerEventsDataKey: "nearest",
|
|
5733
5944
|
children: [
|
|
5734
|
-
|
|
5945
|
+
withTooltips && (withBandHighlight || onBandHighlightChange) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BandHighlight, {
|
|
5946
|
+
visible: withBandHighlight,
|
|
5947
|
+
horizontal,
|
|
5948
|
+
onChange: onBandHighlightChange
|
|
5949
|
+
}),
|
|
5950
|
+
!allSeriesHidden && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_visx_xychart.Grid, {
|
|
5735
5951
|
columns: gridVisibility.includes("y"),
|
|
5952
|
+
rows: false,
|
|
5953
|
+
numTicks: 4,
|
|
5954
|
+
tickValues: chartOptions.axis.x.tickValues
|
|
5955
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_visx_xychart.Grid, {
|
|
5956
|
+
columns: false,
|
|
5736
5957
|
rows: gridVisibility.includes("x"),
|
|
5737
|
-
numTicks: 4
|
|
5738
|
-
|
|
5958
|
+
numTicks: 4,
|
|
5959
|
+
tickValues: chartOptions.axis.y.tickValues
|
|
5960
|
+
})] }),
|
|
5739
5961
|
withPatterns && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("defs", { children: dataSorted.map((seriesData, index) => renderPattern(index, getElementStyles({
|
|
5740
5962
|
data: seriesData,
|
|
5741
5963
|
index
|
|
@@ -5771,8 +5993,17 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height, class
|
|
|
5771
5993
|
colorAccessor: getBarBackground(index)
|
|
5772
5994
|
}, seriesData?.label))
|
|
5773
5995
|
}),
|
|
5996
|
+
(withTooltips || onPointerDown || onPointerUp) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BandTooltip, {
|
|
5997
|
+
keys: primaryKeys,
|
|
5998
|
+
groupPadding,
|
|
5999
|
+
withTooltips,
|
|
6000
|
+
onPointerDown,
|
|
6001
|
+
onPointerUp
|
|
6002
|
+
}),
|
|
5774
6003
|
!allSeriesHidden && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_visx_xychart.Axis, { ...chartOptions.axis.x }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_visx_xychart.Axis, { ...chartOptions.axis.y })] }),
|
|
5775
6004
|
withTooltips && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccessibleTooltip, {
|
|
6005
|
+
tooltipPlacement,
|
|
6006
|
+
tooltipAnchorTop,
|
|
5776
6007
|
detectBounds: true,
|
|
5777
6008
|
snapTooltipToDatumX: true,
|
|
5778
6009
|
snapTooltipToDatumY: true,
|
|
@@ -6594,8 +6825,11 @@ var heatmap_chart_module_default = {
|
|
|
6594
6825
|
"heatmap-chart__gap-start": "a8ccharts-O3YMOW-heatmap-chart__gap-start",
|
|
6595
6826
|
"heatmap-chart__grid": "a8ccharts-O3YMOW-heatmap-chart__grid",
|
|
6596
6827
|
"heatmap-chart__grid--compact": "a8ccharts-O3YMOW-heatmap-chart__grid--compact",
|
|
6828
|
+
"heatmap-chart__grid--flex-gaps": "a8ccharts-O3YMOW-heatmap-chart__grid--flex-gaps",
|
|
6597
6829
|
"heatmap-chart__grid--height-capped": "a8ccharts-O3YMOW-heatmap-chart__grid--height-capped",
|
|
6830
|
+
"heatmap-chart__group-label": "a8ccharts-O3YMOW-heatmap-chart__group-label",
|
|
6598
6831
|
"heatmap-chart__legend-label": "a8ccharts-O3YMOW-heatmap-chart__legend-label",
|
|
6832
|
+
"heatmap-chart__legend-scale--bar": "a8ccharts-O3YMOW-heatmap-chart__legend-scale--bar",
|
|
6599
6833
|
"heatmap-chart__legend-swatch": "a8ccharts-O3YMOW-heatmap-chart__legend-swatch",
|
|
6600
6834
|
"heatmap-chart__row": "a8ccharts-O3YMOW-heatmap-chart__row",
|
|
6601
6835
|
"heatmap-chart__row-label": "a8ccharts-O3YMOW-heatmap-chart__row-label",
|
|
@@ -6645,7 +6879,7 @@ const getNormalizedValue = (value, extent) => {
|
|
|
6645
6879
|
const HeatmapContext = (0, react.createContext)(null);
|
|
6646
6880
|
//#endregion
|
|
6647
6881
|
//#region src/charts/heatmap-chart/private/heatmap-legend.tsx
|
|
6648
|
-
const HeatmapLegend = ({ steps = 5, lessLabel, moreLabel }) => {
|
|
6882
|
+
const HeatmapLegend = ({ steps = 5, variant = "swatches", lessLabel, moreLabel }) => {
|
|
6649
6883
|
const context = (0, react.useContext)(HeatmapContext);
|
|
6650
6884
|
const { legend } = useGlobalChartsTheme();
|
|
6651
6885
|
if (!context) return null;
|
|
@@ -6664,11 +6898,12 @@ const HeatmapLegend = ({ steps = 5, lessLabel, moreLabel }) => {
|
|
|
6664
6898
|
}),
|
|
6665
6899
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_wordpress_ui.Stack, {
|
|
6666
6900
|
direction: "row",
|
|
6667
|
-
gap: "xs",
|
|
6901
|
+
gap: variant === "bar" ? void 0 : "xs",
|
|
6902
|
+
"aria-hidden": "true",
|
|
6903
|
+
className: variant === "bar" ? heatmap_chart_module_default["heatmap-chart__legend-scale--bar"] : void 0,
|
|
6668
6904
|
children: Array.from({ length: steps }, (_, index) => {
|
|
6669
6905
|
const intensity = steps <= 1 ? 1 : index / (steps - 1);
|
|
6670
6906
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6671
|
-
"aria-hidden": "true",
|
|
6672
6907
|
className: heatmap_chart_module_default["heatmap-chart__legend-swatch"],
|
|
6673
6908
|
style: {
|
|
6674
6909
|
"--a8c-charts-color-heatmap-primary": primaryColorHex,
|
|
@@ -6687,16 +6922,219 @@ const HeatmapLegend = ({ steps = 5, lessLabel, moreLabel }) => {
|
|
|
6687
6922
|
});
|
|
6688
6923
|
};
|
|
6689
6924
|
//#endregion
|
|
6925
|
+
//#region src/charts/heatmap-chart/private/column-groups.ts
|
|
6926
|
+
const isSpan = (span) => Number.isInteger(span) && span > 0;
|
|
6927
|
+
/**
|
|
6928
|
+
* Validates column groups and lays them over the columns.
|
|
6929
|
+
*
|
|
6930
|
+
* @param groups - Groups as passed to the chart.
|
|
6931
|
+
* @param columnCount - Number of data columns.
|
|
6932
|
+
* @param firstLine - Grid column line of the first data column.
|
|
6933
|
+
* @return Grid column lines for every column and group; no groups when the input was unusable.
|
|
6934
|
+
*/
|
|
6935
|
+
const resolveColumnGroups = (groups, columnCount, firstLine) => {
|
|
6936
|
+
const ungrouped = () => ({
|
|
6937
|
+
columns: Array.from({ length: columnCount }, (_, index) => ({
|
|
6938
|
+
line: firstLine + index,
|
|
6939
|
+
gapBefore: false
|
|
6940
|
+
})),
|
|
6941
|
+
groups: []
|
|
6942
|
+
});
|
|
6943
|
+
if (!groups || groups.length === 0 || columnCount === 0) return ungrouped();
|
|
6944
|
+
const spans = groups.map((group) => group.span);
|
|
6945
|
+
const total = spans.reduce((sum, span) => sum + span, 0);
|
|
6946
|
+
if (!spans.every(isSpan) || total > columnCount) {
|
|
6947
|
+
warnOnce(`heatmap:columnGroups:${JSON.stringify(spans)}:${columnCount}`, `columnGroups spans ${JSON.stringify(spans)} must be positive integers that fit the ${columnCount} columns, so no groups are drawn.`);
|
|
6948
|
+
return ungrouped();
|
|
6949
|
+
}
|
|
6950
|
+
const columns = [];
|
|
6951
|
+
const laidOut = [];
|
|
6952
|
+
let line = firstLine;
|
|
6953
|
+
groups.forEach((group, groupIndex) => {
|
|
6954
|
+
if (groupIndex > 0) line += 1;
|
|
6955
|
+
laidOut.push({
|
|
6956
|
+
...group,
|
|
6957
|
+
line
|
|
6958
|
+
});
|
|
6959
|
+
for (let offset = 0; offset < group.span; offset++) {
|
|
6960
|
+
columns.push({
|
|
6961
|
+
line,
|
|
6962
|
+
gapBefore: groupIndex > 0 && offset === 0,
|
|
6963
|
+
group: groupIndex
|
|
6964
|
+
});
|
|
6965
|
+
line += 1;
|
|
6966
|
+
}
|
|
6967
|
+
});
|
|
6968
|
+
while (columns.length < columnCount) {
|
|
6969
|
+
columns.push({
|
|
6970
|
+
line,
|
|
6971
|
+
gapBefore: false
|
|
6972
|
+
});
|
|
6973
|
+
line += 1;
|
|
6974
|
+
}
|
|
6975
|
+
return {
|
|
6976
|
+
columns,
|
|
6977
|
+
groups: laidOut
|
|
6978
|
+
};
|
|
6979
|
+
};
|
|
6980
|
+
//#endregion
|
|
6981
|
+
//#region src/charts/heatmap-chart/private/keyboard-navigation.ts
|
|
6982
|
+
const ARROW_KEYS = [
|
|
6983
|
+
"ArrowLeft",
|
|
6984
|
+
"ArrowRight",
|
|
6985
|
+
"ArrowUp",
|
|
6986
|
+
"ArrowDown"
|
|
6987
|
+
];
|
|
6988
|
+
const PAGE_KEYS = ["PageUp", "PageDown"];
|
|
6989
|
+
const isNavigationKey = (key, mode) => ARROW_KEYS.includes(key) || mode === "calendar" && PAGE_KEYS.includes(key);
|
|
6990
|
+
const inGrid = (grid, { column, row }) => column >= 0 && column < grid.columns && row >= 0 && row < grid.rows;
|
|
6991
|
+
const firstSelectable = (grid, cells) => cells.find((cell) => inGrid(grid, cell) && !grid.isInert(cell.column, cell.row));
|
|
6992
|
+
/**
|
|
6993
|
+
* Column-major scan for the first selectable cell.
|
|
6994
|
+
*
|
|
6995
|
+
* @param grid - The grid.
|
|
6996
|
+
* @return The cell, or undefined when every slot is inert.
|
|
6997
|
+
*/
|
|
6998
|
+
const firstGridCell = (grid) => {
|
|
6999
|
+
for (let column = 0; column < grid.columns; column++) for (let row = 0; row < grid.rows; row++) if (!grid.isInert(column, row)) return {
|
|
7000
|
+
column,
|
|
7001
|
+
row
|
|
7002
|
+
};
|
|
7003
|
+
};
|
|
7004
|
+
/**
|
|
7005
|
+
* Steps across the grid in the key's direction, past inert slots, staying put at the edge.
|
|
7006
|
+
*
|
|
7007
|
+
* @param grid - The grid.
|
|
7008
|
+
* @param from - The selected cell.
|
|
7009
|
+
* @param key - The arrow key.
|
|
7010
|
+
* @return The next cell, or undefined to keep the selection.
|
|
7011
|
+
*/
|
|
7012
|
+
const stepGridCell = (grid, from, key) => {
|
|
7013
|
+
const step = {
|
|
7014
|
+
ArrowRight: [1, 0],
|
|
7015
|
+
ArrowLeft: [-1, 0],
|
|
7016
|
+
ArrowDown: [0, 1],
|
|
7017
|
+
ArrowUp: [0, -1]
|
|
7018
|
+
}[key];
|
|
7019
|
+
if (!step) return;
|
|
7020
|
+
const [stepColumn, stepRow] = step;
|
|
7021
|
+
let cell = from;
|
|
7022
|
+
do
|
|
7023
|
+
cell = {
|
|
7024
|
+
column: cell.column + stepColumn,
|
|
7025
|
+
row: cell.row + stepRow
|
|
7026
|
+
};
|
|
7027
|
+
while (inGrid(grid, cell) && grid.isInert(cell.column, cell.row));
|
|
7028
|
+
return inGrid(grid, cell) ? cell : void 0;
|
|
7029
|
+
};
|
|
7030
|
+
/**
|
|
7031
|
+
* Every slot of the blocks in reading order: block by block, each a row at a time.
|
|
7032
|
+
*
|
|
7033
|
+
* @param grid - The grid.
|
|
7034
|
+
* @param blocks - The blocks, left to right.
|
|
7035
|
+
* @return The slots in order.
|
|
7036
|
+
*/
|
|
7037
|
+
const readingOrder = (grid, blocks) => blocks.flatMap((block) => Array.from({ length: grid.rows }, (_row, row) => Array.from({ length: block.end - block.start }, (_offset, offset) => ({
|
|
7038
|
+
column: block.start + offset,
|
|
7039
|
+
row
|
|
7040
|
+
}))).flat());
|
|
7041
|
+
const blockOf = (blocks, column) => blocks.findIndex((block) => column >= block.start && column < block.end);
|
|
7042
|
+
/**
|
|
7043
|
+
* The slots after a cell down its column (or before it, going up), continuing at the
|
|
7044
|
+
* same column offset of each following block.
|
|
7045
|
+
*
|
|
7046
|
+
* @param grid - The grid.
|
|
7047
|
+
* @param blocks - The blocks, left to right.
|
|
7048
|
+
* @param from - The selected cell.
|
|
7049
|
+
* @param direction - 1 downwards, -1 upwards.
|
|
7050
|
+
* @return The slots in order.
|
|
7051
|
+
*/
|
|
7052
|
+
const columnOrderFrom = (grid, blocks, from, direction) => {
|
|
7053
|
+
const blockIndex = blockOf(blocks, from.column);
|
|
7054
|
+
if (blockIndex < 0) return [];
|
|
7055
|
+
const offset = from.column - blocks[blockIndex].start;
|
|
7056
|
+
const cells = [];
|
|
7057
|
+
const pushRows = (column, startRow) => {
|
|
7058
|
+
for (let row = startRow; row >= 0 && row < grid.rows; row += direction) cells.push({
|
|
7059
|
+
column,
|
|
7060
|
+
row
|
|
7061
|
+
});
|
|
7062
|
+
};
|
|
7063
|
+
pushRows(from.column, from.row + direction);
|
|
7064
|
+
for (let index = blockIndex + direction; index >= 0 && index < blocks.length; index += direction) {
|
|
7065
|
+
const column = blocks[index].start + offset;
|
|
7066
|
+
if (column < blocks[index].end) pushRows(column, direction === 1 ? 0 : grid.rows - 1);
|
|
7067
|
+
}
|
|
7068
|
+
return cells;
|
|
7069
|
+
};
|
|
7070
|
+
/**
|
|
7071
|
+
* The first selectable cell in calendar reading order.
|
|
7072
|
+
*
|
|
7073
|
+
* @param grid - The grid.
|
|
7074
|
+
* @param blocks - The blocks, left to right.
|
|
7075
|
+
* @return The cell, or undefined when every slot is inert.
|
|
7076
|
+
*/
|
|
7077
|
+
const firstCalendarCell = (grid, blocks) => firstSelectable(grid, readingOrder(grid, blocks));
|
|
7078
|
+
/**
|
|
7079
|
+
* Steps through the blocks as pages of a calendar: Left/Right by one slot in reading
|
|
7080
|
+
* order, Up/Down by one row (into the neighboring block past the edge), Page Up/Down
|
|
7081
|
+
* to the same slot of the neighboring block or its nearest selectable cell.
|
|
7082
|
+
*
|
|
7083
|
+
* @param grid - The grid.
|
|
7084
|
+
* @param blocks - The blocks, left to right.
|
|
7085
|
+
* @param from - The selected cell.
|
|
7086
|
+
* @param key - The navigation key.
|
|
7087
|
+
* @return The next cell, or undefined to keep the selection.
|
|
7088
|
+
*/
|
|
7089
|
+
const stepCalendarCell = (grid, blocks, from, key) => {
|
|
7090
|
+
if (key === "ArrowRight" || key === "ArrowLeft") {
|
|
7091
|
+
const order = readingOrder(grid, blocks);
|
|
7092
|
+
const index = order.findIndex((cell) => cell.column === from.column && cell.row === from.row);
|
|
7093
|
+
if (index < 0) return;
|
|
7094
|
+
const ahead = key === "ArrowRight" ? order.slice(index + 1) : order.slice(0, index).reverse();
|
|
7095
|
+
return firstSelectable(grid, ahead);
|
|
7096
|
+
}
|
|
7097
|
+
if (key === "ArrowDown" || key === "ArrowUp") return firstSelectable(grid, columnOrderFrom(grid, blocks, from, key === "ArrowDown" ? 1 : -1));
|
|
7098
|
+
const blockIndex = blockOf(blocks, from.column);
|
|
7099
|
+
const target = blocks[blockIndex + (key === "PageDown" ? 1 : -1)];
|
|
7100
|
+
if (blockIndex < 0 || !target) return;
|
|
7101
|
+
const same = {
|
|
7102
|
+
column: target.start + (from.column - blocks[blockIndex].start),
|
|
7103
|
+
row: from.row
|
|
7104
|
+
};
|
|
7105
|
+
const page = readingOrder(grid, [target]);
|
|
7106
|
+
const at = page.findIndex((cell) => cell.row > same.row || cell.row === same.row && cell.column >= same.column);
|
|
7107
|
+
const after = at === -1 ? [] : page.slice(at);
|
|
7108
|
+
const before = page.slice(0, at === -1 ? page.length : at).reverse();
|
|
7109
|
+
return firstSelectable(grid, after) ?? firstSelectable(grid, before);
|
|
7110
|
+
};
|
|
7111
|
+
//#endregion
|
|
6690
7112
|
//#region src/charts/heatmap-chart/heatmap-chart.tsx
|
|
6691
7113
|
const CELL_MIX_FLOOR = .15;
|
|
6692
7114
|
const NO_ROW_LABELS = [];
|
|
6693
|
-
const
|
|
7115
|
+
const TOOLTIP_BOX_STYLES = {
|
|
7116
|
+
light: {
|
|
7117
|
+
..._visx_tooltip.defaultStyles,
|
|
7118
|
+
zIndex: 3
|
|
7119
|
+
},
|
|
7120
|
+
dark: { zIndex: 3 }
|
|
7121
|
+
};
|
|
7122
|
+
const cellName = (info) => info.cellLabel || [
|
|
7123
|
+
info.groupLabel,
|
|
7124
|
+
info.columnLabel,
|
|
7125
|
+
info.rowLabel
|
|
7126
|
+
].filter(Boolean).join(" ");
|
|
7127
|
+
const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, height = 0, className, compact = false, showValues, maxCellWidth, maxCellHeight, minCellWidth, minCellHeight, rowLabels = NO_ROW_LABELS, columnGroups, keyboardNavigation = "grid", ariaLabel, primaryColor, gap = "md", withTooltips = false, renderTooltip, tooltipVariant = "light", tooltipStyle, children }) => {
|
|
6694
7128
|
const chartId = useChartId(providedChartId);
|
|
7129
|
+
const tooltipBoxStyle = tooltipStyle ? {
|
|
7130
|
+
...TOOLTIP_BOX_STYLES[tooltipVariant],
|
|
7131
|
+
...tooltipStyle
|
|
7132
|
+
} : TOOLTIP_BOX_STYLES[tooltipVariant];
|
|
6695
7133
|
const { getElementStyles, theme } = useGlobalChartsContext();
|
|
6696
7134
|
const scopeElement = useChartScopeElement();
|
|
6697
7135
|
const { heatmapChart: heatmapChartSettings } = theme;
|
|
6698
7136
|
const { nonLegendChildren } = useChartChildren(children, "HeatmapChart");
|
|
6699
|
-
const [
|
|
7137
|
+
const [selected, setSelected] = (0, react.useState)();
|
|
6700
7138
|
const { tooltipOpen, tooltipLeft, tooltipTop, tooltipData, showTooltip, hideTooltip } = (0, _visx_tooltip.useTooltip)();
|
|
6701
7139
|
const standaloneScopeClass = useStandaloneScopeClass();
|
|
6702
7140
|
const containerRef = (0, react.useRef)(null);
|
|
@@ -6715,69 +7153,75 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
6715
7153
|
}), [extent, primaryColorHex]);
|
|
6716
7154
|
const columns = data.length;
|
|
6717
7155
|
const rows = Math.max(0, ...data.map((column) => column.data.length));
|
|
6718
|
-
const
|
|
7156
|
+
const groupLayout = (0, react.useMemo)(() => resolveColumnGroups(columnGroups, columns, 2), [columnGroups, columns]);
|
|
7157
|
+
const { compactCellGap, compactCellSize, groupGap } = heatmapChartSettings;
|
|
6719
7158
|
const drawValues = showValues ?? !compact;
|
|
6720
7159
|
const buildTooltipData = (0, react.useCallback)((columnIndex, rowIndex) => {
|
|
6721
7160
|
const cell = data[columnIndex]?.data[rowIndex];
|
|
7161
|
+
const group = groupLayout.columns[columnIndex]?.group;
|
|
6722
7162
|
return {
|
|
6723
7163
|
value: cell?.value ?? null,
|
|
6724
7164
|
rowLabel: rowLabels[rowIndex],
|
|
6725
7165
|
columnLabel: data[columnIndex]?.label,
|
|
7166
|
+
groupLabel: group === void 0 ? void 0 : groupLayout.groups[group]?.label,
|
|
6726
7167
|
cellLabel: cell?.label,
|
|
6727
7168
|
row: rowIndex,
|
|
6728
7169
|
column: columnIndex
|
|
6729
7170
|
};
|
|
6730
|
-
}, [
|
|
7171
|
+
}, [
|
|
7172
|
+
data,
|
|
7173
|
+
rowLabels,
|
|
7174
|
+
groupLayout
|
|
7175
|
+
]);
|
|
6731
7176
|
const onChartBlur = (0, react.useCallback)(() => {
|
|
6732
|
-
|
|
7177
|
+
setSelected(void 0);
|
|
6733
7178
|
hideTooltip();
|
|
6734
7179
|
}, [hideTooltip]);
|
|
6735
7180
|
const isCellInert = (0, react.useCallback)((col, row) => {
|
|
6736
7181
|
const cell = data[col]?.data[row];
|
|
6737
7182
|
return cell?.hidden === true || cell?.placeholder === true;
|
|
6738
7183
|
}, [data]);
|
|
7184
|
+
const blocks = (0, react.useMemo)(() => {
|
|
7185
|
+
const grouped = groupLayout.groups.map((group, index) => {
|
|
7186
|
+
const start = groupLayout.columns.findIndex((column) => column.group === index);
|
|
7187
|
+
return {
|
|
7188
|
+
start,
|
|
7189
|
+
end: start + group.span
|
|
7190
|
+
};
|
|
7191
|
+
});
|
|
7192
|
+
const groupedEnd = grouped.length ? grouped[grouped.length - 1].end : 0;
|
|
7193
|
+
return groupedEnd < columns ? [...grouped, {
|
|
7194
|
+
start: groupedEnd,
|
|
7195
|
+
end: columns
|
|
7196
|
+
}] : grouped;
|
|
7197
|
+
}, [groupLayout, columns]);
|
|
6739
7198
|
const onChartKeyDown = (0, react.useCallback)((event) => {
|
|
6740
|
-
if (![
|
|
6741
|
-
"ArrowLeft",
|
|
6742
|
-
"ArrowRight",
|
|
6743
|
-
"ArrowUp",
|
|
6744
|
-
"ArrowDown",
|
|
6745
|
-
"Escape",
|
|
6746
|
-
"Tab"
|
|
6747
|
-
].includes(event.key)) return;
|
|
6748
7199
|
if (event.key === "Tab" || event.key === "Escape") {
|
|
6749
|
-
|
|
7200
|
+
setSelected(void 0);
|
|
6750
7201
|
hideTooltip();
|
|
6751
7202
|
return;
|
|
6752
7203
|
}
|
|
7204
|
+
if (!isNavigationKey(event.key, keyboardNavigation)) return;
|
|
6753
7205
|
event.preventDefault();
|
|
6754
|
-
|
|
6755
|
-
|
|
6756
|
-
|
|
6757
|
-
|
|
6758
|
-
|
|
7206
|
+
const grid = {
|
|
7207
|
+
columns,
|
|
7208
|
+
rows,
|
|
7209
|
+
isInert: isCellInert
|
|
7210
|
+
};
|
|
7211
|
+
if (selected === void 0) {
|
|
7212
|
+
setSelected(keyboardNavigation === "calendar" ? firstCalendarCell(grid, blocks) : firstGridCell(grid));
|
|
6759
7213
|
return;
|
|
6760
7214
|
}
|
|
6761
|
-
|
|
6762
|
-
|
|
6763
|
-
if (event.key === "ArrowRight") stepCol = 1;
|
|
6764
|
-
else if (event.key === "ArrowLeft") stepCol = -1;
|
|
6765
|
-
else if (event.key === "ArrowDown") stepRow = 1;
|
|
6766
|
-
else if (event.key === "ArrowUp") stepRow = -1;
|
|
6767
|
-
let col = Math.floor(selectedIndex / rows);
|
|
6768
|
-
let row = selectedIndex % rows;
|
|
6769
|
-
do {
|
|
6770
|
-
col += stepCol;
|
|
6771
|
-
row += stepRow;
|
|
6772
|
-
} while (col >= 0 && col < columns && row >= 0 && row < rows && isCellInert(col, row));
|
|
6773
|
-
if (col < 0 || col >= columns || row < 0 || row >= rows) return;
|
|
6774
|
-
setSelectedIndex(col * rows + row);
|
|
7215
|
+
const next = keyboardNavigation === "calendar" ? stepCalendarCell(grid, blocks, selected, event.key) : stepGridCell(grid, selected, event.key);
|
|
7216
|
+
if (next) setSelected(next);
|
|
6775
7217
|
}, [
|
|
6776
7218
|
rows,
|
|
6777
7219
|
columns,
|
|
6778
|
-
|
|
7220
|
+
selected,
|
|
6779
7221
|
hideTooltip,
|
|
6780
|
-
isCellInert
|
|
7222
|
+
isCellInert,
|
|
7223
|
+
keyboardNavigation,
|
|
7224
|
+
blocks
|
|
6781
7225
|
]);
|
|
6782
7226
|
const handleCellMouseMove = (0, react.useCallback)((event) => {
|
|
6783
7227
|
if (!withTooltips) return;
|
|
@@ -6797,35 +7241,47 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
6797
7241
|
buildTooltipData,
|
|
6798
7242
|
getTooltipOrigin
|
|
6799
7243
|
]);
|
|
7244
|
+
const getCellElement = (0, react.useCallback)((col, row) => typeof document !== "undefined" ? document.getElementById(`${chartId}-cell-${col}-${row}`) : null, [chartId]);
|
|
6800
7245
|
const handleCellMouseLeave = (0, react.useCallback)(() => {
|
|
6801
|
-
if (withTooltips &&
|
|
7246
|
+
if (withTooltips && selected === void 0) hideTooltip();
|
|
6802
7247
|
}, [
|
|
6803
7248
|
withTooltips,
|
|
6804
|
-
|
|
7249
|
+
selected,
|
|
6805
7250
|
hideTooltip
|
|
6806
7251
|
]);
|
|
6807
7252
|
(0, react.useEffect)(() => {
|
|
6808
|
-
if (
|
|
7253
|
+
if (selected && (selected.column >= columns || selected.row >= rows)) setSelected(void 0);
|
|
7254
|
+
}, [
|
|
7255
|
+
selected,
|
|
7256
|
+
columns,
|
|
7257
|
+
rows
|
|
7258
|
+
]);
|
|
7259
|
+
(0, react.useEffect)(() => {
|
|
7260
|
+
if (selected === void 0) return;
|
|
7261
|
+
getCellElement(selected.column, selected.row)?.scrollIntoView?.({
|
|
7262
|
+
block: "nearest",
|
|
7263
|
+
inline: "nearest"
|
|
7264
|
+
});
|
|
7265
|
+
}, [selected, getCellElement]);
|
|
7266
|
+
(0, react.useEffect)(() => {
|
|
7267
|
+
if (!withTooltips || selected === void 0) return;
|
|
6809
7268
|
const origin = getTooltipOrigin();
|
|
6810
7269
|
if (!origin) return;
|
|
6811
|
-
const
|
|
6812
|
-
const row = selectedIndex % rows;
|
|
6813
|
-
const rect = (typeof document !== "undefined" ? document.getElementById(`${chartId}-cell-${col}-${row}`) : null)?.getBoundingClientRect();
|
|
7270
|
+
const rect = getCellElement(selected.column, selected.row)?.getBoundingClientRect();
|
|
6814
7271
|
showTooltip({
|
|
6815
7272
|
tooltipLeft: rect ? rect.left + rect.width / 2 - origin.left : 0,
|
|
6816
7273
|
tooltipTop: rect ? rect.top + rect.height / 2 - origin.top : 0,
|
|
6817
|
-
tooltipData: buildTooltipData(
|
|
7274
|
+
tooltipData: buildTooltipData(selected.column, selected.row)
|
|
6818
7275
|
});
|
|
6819
7276
|
}, [
|
|
6820
|
-
|
|
7277
|
+
selected,
|
|
6821
7278
|
withTooltips,
|
|
6822
|
-
|
|
6823
|
-
chartId,
|
|
7279
|
+
getCellElement,
|
|
6824
7280
|
buildTooltipData,
|
|
6825
7281
|
showTooltip,
|
|
6826
7282
|
getTooltipOrigin
|
|
6827
7283
|
]);
|
|
6828
|
-
const defaultRenderTooltip = (0, react.useCallback)((info) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: info
|
|
7284
|
+
const defaultRenderTooltip = (0, react.useCallback)((info) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: cellName(info) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: info.value === null ? (0, _wordpress_i18n.__)("No data", "jetpack-charts") : (0, _automattic_number_formatters.formatNumber)(info.value) })] }), []);
|
|
6829
7285
|
if (!columns || !rows) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Center, {
|
|
6830
7286
|
className: (0, clsx.default)("heatmap-chart", heatmap_chart_module_default["heatmap-chart"], className),
|
|
6831
7287
|
style: {
|
|
@@ -6839,10 +7295,16 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
6839
7295
|
});
|
|
6840
7296
|
const columnTrack = compact ? "var(--a8c-charts-dimension-heatmap-cell-size)" : `minmax(${minCellWidth ?? 0}px, ${maxCellWidth ? `${maxCellWidth}px` : "1fr"})`;
|
|
6841
7297
|
const rowTrack = compact ? "var(--a8c-charts-dimension-heatmap-cell-size)" : `minmax(${minCellHeight ?? 0}px, ${maxCellHeight ? `${maxCellHeight}px` : "1fr"})`;
|
|
7298
|
+
const hasColumnLabels = data.some((column) => Boolean(column.label));
|
|
7299
|
+
const hasGroups = groupLayout.groups.length > 0;
|
|
7300
|
+
const columnLine = (columnIndex) => groupLayout.columns[columnIndex].line;
|
|
7301
|
+
const firstDataRow = hasColumnLabels ? 2 : 1;
|
|
7302
|
+
const dataTrack = (column) => column.summary ? "minmax(auto, max-content)" : columnTrack;
|
|
7303
|
+
const gapTrack = compact ? `minmax(${groupGap}px, 1fr)` : `${groupGap}px`;
|
|
6842
7304
|
const gridStyle = {
|
|
6843
7305
|
"--a8c-charts-color-heatmap-primary": primaryColorHex,
|
|
6844
|
-
gridTemplateColumns: `auto ${data.
|
|
6845
|
-
gridTemplateRows:
|
|
7306
|
+
gridTemplateColumns: `auto ${data.map((column, columnIndex) => groupLayout.columns[columnIndex].gapBefore ? `${gapTrack} ${dataTrack(column)}` : dataTrack(column)).join(" ")}`,
|
|
7307
|
+
gridTemplateRows: `${hasColumnLabels ? "auto " : ""}repeat(${rows}, ${rowTrack})${hasGroups ? " auto" : ""}`
|
|
6846
7308
|
};
|
|
6847
7309
|
if (compact) {
|
|
6848
7310
|
gridStyle["--a8c-charts-dimension-heatmap-cell-gap"] = `${compactCellGap}px`;
|
|
@@ -6855,7 +7317,7 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
6855
7317
|
[heatmap_chart_module_default["heatmap-chart__gap-end"]]: columnIndex < columns - 1 && !data[columnIndex + 1]?.summary
|
|
6856
7318
|
};
|
|
6857
7319
|
};
|
|
6858
|
-
const activeDescendant =
|
|
7320
|
+
const activeDescendant = selected ? `${chartId}-cell-${selected.column}-${selected.row}` : void 0;
|
|
6859
7321
|
const heightCapped = !compact && Boolean(maxCellHeight);
|
|
6860
7322
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeatmapContext.Provider, {
|
|
6861
7323
|
value: heatmapContext,
|
|
@@ -6875,7 +7337,7 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
6875
7337
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6876
7338
|
ref: containerRef,
|
|
6877
7339
|
role: "grid",
|
|
6878
|
-
"aria-label": (0, _wordpress_i18n.__)("Heatmap chart", "jetpack-charts"),
|
|
7340
|
+
"aria-label": ariaLabel ?? (0, _wordpress_i18n.__)("Heatmap chart", "jetpack-charts"),
|
|
6879
7341
|
"aria-rowcount": rows,
|
|
6880
7342
|
"aria-colcount": columns,
|
|
6881
7343
|
"aria-activedescendant": activeDescendant,
|
|
@@ -6884,76 +7346,115 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
6884
7346
|
onKeyDown: onChartKeyDown,
|
|
6885
7347
|
className: (0, clsx.default)(heatmap_chart_module_default["heatmap-chart__grid"], {
|
|
6886
7348
|
[heatmap_chart_module_default["heatmap-chart__grid--compact"]]: compact,
|
|
7349
|
+
[heatmap_chart_module_default["heatmap-chart__grid--flex-gaps"]]: compact && hasGroups,
|
|
6887
7350
|
[heatmap_chart_module_default["heatmap-chart__grid--height-capped"]]: heightCapped
|
|
6888
7351
|
}),
|
|
6889
7352
|
style: gridStyle,
|
|
6890
|
-
children: [
|
|
6891
|
-
|
|
6892
|
-
"aria-hidden": "true",
|
|
6893
|
-
className: heatmap_chart_module_default["heatmap-chart__row"],
|
|
6894
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {}), data.map((column, columnIndex) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6895
|
-
className: (0, clsx.default)(heatmap_chart_module_default["heatmap-chart__col-label"], {
|
|
6896
|
-
[heatmap_chart_module_default["heatmap-chart__col-label--summary"]]: column.summary,
|
|
6897
|
-
...summaryGaps(columnIndex)
|
|
6898
|
-
}),
|
|
6899
|
-
children: column.label
|
|
6900
|
-
}, `col-${columnIndex}`))]
|
|
6901
|
-
}), Array.from({ length: rows }).map((_row, rowIndex) => {
|
|
6902
|
-
const labelVisible = !compact || rowIndex % 2 === 0;
|
|
6903
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7353
|
+
children: [
|
|
7354
|
+
hasColumnLabels && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6904
7355
|
role: "row",
|
|
6905
|
-
"aria-
|
|
7356
|
+
"aria-hidden": "true",
|
|
6906
7357
|
className: heatmap_chart_module_default["heatmap-chart__row"],
|
|
6907
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6908
|
-
|
|
6909
|
-
|
|
6910
|
-
|
|
6911
|
-
|
|
6912
|
-
|
|
6913
|
-
|
|
6914
|
-
|
|
6915
|
-
|
|
6916
|
-
|
|
6917
|
-
|
|
7358
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: {
|
|
7359
|
+
gridColumn: 1,
|
|
7360
|
+
gridRow: 1
|
|
7361
|
+
} }), data.map((column, columnIndex) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7362
|
+
style: {
|
|
7363
|
+
gridColumn: columnLine(columnIndex),
|
|
7364
|
+
gridRow: 1
|
|
7365
|
+
},
|
|
7366
|
+
className: (0, clsx.default)(heatmap_chart_module_default["heatmap-chart__col-label"], {
|
|
7367
|
+
[heatmap_chart_module_default["heatmap-chart__col-label--summary"]]: column.summary,
|
|
7368
|
+
...summaryGaps(columnIndex)
|
|
7369
|
+
}),
|
|
7370
|
+
children: column.label
|
|
7371
|
+
}, `col-${columnIndex}`))]
|
|
7372
|
+
}),
|
|
7373
|
+
Array.from({ length: rows }).map((_row, rowIndex) => {
|
|
7374
|
+
const labelVisible = !compact || rowIndex % 2 === 0;
|
|
7375
|
+
const gridRow = firstDataRow + rowIndex;
|
|
7376
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7377
|
+
role: "row",
|
|
7378
|
+
"aria-rowindex": rowIndex + 1,
|
|
7379
|
+
className: heatmap_chart_module_default["heatmap-chart__row"],
|
|
7380
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6918
7381
|
"aria-hidden": "true",
|
|
6919
|
-
className:
|
|
6920
|
-
|
|
6921
|
-
|
|
6922
|
-
|
|
6923
|
-
|
|
6924
|
-
|
|
6925
|
-
|
|
6926
|
-
|
|
6927
|
-
|
|
6928
|
-
|
|
6929
|
-
|
|
6930
|
-
|
|
6931
|
-
|
|
6932
|
-
|
|
6933
|
-
|
|
6934
|
-
|
|
6935
|
-
|
|
6936
|
-
|
|
6937
|
-
|
|
6938
|
-
|
|
6939
|
-
[heatmap_chart_module_default["heatmap-chart__cell--
|
|
6940
|
-
|
|
6941
|
-
|
|
6942
|
-
|
|
6943
|
-
|
|
6944
|
-
|
|
6945
|
-
|
|
6946
|
-
|
|
6947
|
-
|
|
6948
|
-
|
|
6949
|
-
|
|
6950
|
-
|
|
6951
|
-
|
|
6952
|
-
|
|
6953
|
-
|
|
7382
|
+
className: heatmap_chart_module_default["heatmap-chart__row-label"],
|
|
7383
|
+
style: {
|
|
7384
|
+
gridColumn: 1,
|
|
7385
|
+
gridRow
|
|
7386
|
+
},
|
|
7387
|
+
children: labelVisible ? rowLabels[rowIndex] ?? "" : ""
|
|
7388
|
+
}), data.map((column, columnIndex) => {
|
|
7389
|
+
const cell = column.data[rowIndex];
|
|
7390
|
+
const placement = {
|
|
7391
|
+
gridColumn: columnLine(columnIndex),
|
|
7392
|
+
gridRow
|
|
7393
|
+
};
|
|
7394
|
+
if (cell?.hidden) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7395
|
+
"aria-hidden": "true",
|
|
7396
|
+
style: placement,
|
|
7397
|
+
className: (0, clsx.default)(heatmap_chart_module_default["heatmap-chart__cell"], heatmap_chart_module_default["heatmap-chart__cell--hidden"])
|
|
7398
|
+
}, `cell-${columnIndex}-${rowIndex}`);
|
|
7399
|
+
if (cell?.placeholder) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7400
|
+
"aria-hidden": "true",
|
|
7401
|
+
style: placement,
|
|
7402
|
+
className: (0, clsx.default)(heatmap_chart_module_default["heatmap-chart__cell"], heatmap_chart_module_default["heatmap-chart__cell--placeholder"])
|
|
7403
|
+
}, `cell-${columnIndex}-${rowIndex}`);
|
|
7404
|
+
const value = cell?.value ?? null;
|
|
7405
|
+
const present = isPresent(value);
|
|
7406
|
+
const filled = present && !column.summary;
|
|
7407
|
+
const normalized = filled ? getNormalizedValue(value, extent) : 0;
|
|
7408
|
+
const info = buildTooltipData(columnIndex, rowIndex);
|
|
7409
|
+
const accessibleLabel = `${cellName(info)}: ${info.value === null ? (0, _wordpress_i18n.__)("No data", "jetpack-charts") : (0, _automattic_number_formatters.formatNumber)(info.value)}`;
|
|
7410
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7411
|
+
id: `${chartId}-cell-${columnIndex}-${rowIndex}`,
|
|
7412
|
+
role: "gridcell",
|
|
7413
|
+
tabIndex: -1,
|
|
7414
|
+
"aria-colindex": columnIndex + 1,
|
|
7415
|
+
"aria-label": accessibleLabel,
|
|
7416
|
+
"data-column": columnIndex,
|
|
7417
|
+
"data-row": rowIndex,
|
|
7418
|
+
className: (0, clsx.default)(heatmap_chart_module_default["heatmap-chart__cell"], {
|
|
7419
|
+
[heatmap_chart_module_default["heatmap-chart__cell--filled"]]: filled,
|
|
7420
|
+
[heatmap_chart_module_default["heatmap-chart__cell--strong"]]: filled && cellHasLightText(normalized),
|
|
7421
|
+
[heatmap_chart_module_default["heatmap-chart__cell--summary"]]: column.summary,
|
|
7422
|
+
...summaryGaps(columnIndex),
|
|
7423
|
+
[heatmap_chart_module_default["heatmap-chart__cell--selected"]]: selected?.column === columnIndex && selected?.row === rowIndex
|
|
7424
|
+
}),
|
|
7425
|
+
style: {
|
|
7426
|
+
...placement,
|
|
7427
|
+
...filled ? { "--a8c-charts-heatmap-cell-intensity": normalized } : {}
|
|
7428
|
+
},
|
|
7429
|
+
onMouseMove: handleCellMouseMove,
|
|
7430
|
+
onMouseLeave: handleCellMouseLeave,
|
|
7431
|
+
children: (drawValues || column.summary) && present && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7432
|
+
className: heatmap_chart_module_default["heatmap-chart__cell-value"],
|
|
7433
|
+
children: (0, _automattic_number_formatters.formatNumberCompact)(value)
|
|
7434
|
+
})
|
|
7435
|
+
}, `cell-${columnIndex}-${rowIndex}`);
|
|
7436
|
+
})]
|
|
7437
|
+
}, `row-${rowIndex}`);
|
|
7438
|
+
}),
|
|
7439
|
+
hasGroups && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7440
|
+
role: "row",
|
|
7441
|
+
"aria-hidden": "true",
|
|
7442
|
+
className: heatmap_chart_module_default["heatmap-chart__row"],
|
|
7443
|
+
children: groupLayout.groups.map((group, groupIndex) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7444
|
+
className: heatmap_chart_module_default["heatmap-chart__group-label"],
|
|
7445
|
+
style: {
|
|
7446
|
+
gridColumn: `${group.line} / span ${group.span}`,
|
|
7447
|
+
gridRow: firstDataRow + rows
|
|
7448
|
+
},
|
|
7449
|
+
children: group.label
|
|
7450
|
+
}, `group-${groupIndex}`))
|
|
7451
|
+
})
|
|
7452
|
+
]
|
|
6954
7453
|
}), withTooltips && tooltipOpen && tooltipData && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BoundedTooltip, {
|
|
6955
7454
|
top: tooltipTop,
|
|
6956
7455
|
left: tooltipLeft,
|
|
7456
|
+
className: tooltipVariant === "dark" ? base_tooltip_module_default.surface : void 0,
|
|
7457
|
+
style: tooltipBoxStyle,
|
|
6957
7458
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6958
7459
|
className: standaloneScopeClass,
|
|
6959
7460
|
role: "tooltip",
|
|
@@ -6989,6 +7490,43 @@ const KEY_OPTIONS = {
|
|
|
6989
7490
|
day: "2-digit"
|
|
6990
7491
|
};
|
|
6991
7492
|
const DATE_PREFIX = /^(\d{4})-(\d{2})-(\d{2})/;
|
|
7493
|
+
/**
|
|
7494
|
+
* Label formatters for UTC proxies, so both calendar layouts name a day alike.
|
|
7495
|
+
*
|
|
7496
|
+
* `gregory` keeps a locale whose default calendar is not Gregorian (fa-IR) from
|
|
7497
|
+
* splitting one grid month across two names.
|
|
7498
|
+
*
|
|
7499
|
+
* @param locale - BCP 47 locale.
|
|
7500
|
+
* @return Weekday, month and full-day formatters.
|
|
7501
|
+
*/
|
|
7502
|
+
const civilLabelFormatters = (locale) => {
|
|
7503
|
+
const formatting = {
|
|
7504
|
+
locale,
|
|
7505
|
+
timeZone: "UTC"
|
|
7506
|
+
};
|
|
7507
|
+
return {
|
|
7508
|
+
formatWeekday: createDateFormatter({
|
|
7509
|
+
weekday: "short",
|
|
7510
|
+
calendar: "gregory"
|
|
7511
|
+
}, formatting),
|
|
7512
|
+
formatMonth: createDateFormatter({
|
|
7513
|
+
month: "short",
|
|
7514
|
+
calendar: "gregory"
|
|
7515
|
+
}, formatting),
|
|
7516
|
+
formatMonthYear: createDateFormatter({
|
|
7517
|
+
month: "short",
|
|
7518
|
+
year: "numeric",
|
|
7519
|
+
calendar: "gregory"
|
|
7520
|
+
}, formatting),
|
|
7521
|
+
formatDay: createDateFormatter({
|
|
7522
|
+
weekday: "short",
|
|
7523
|
+
month: "short",
|
|
7524
|
+
day: "numeric",
|
|
7525
|
+
year: "numeric",
|
|
7526
|
+
calendar: "gregory"
|
|
7527
|
+
}, formatting)
|
|
7528
|
+
};
|
|
7529
|
+
};
|
|
6992
7530
|
const pad = (value, length) => String(value).padStart(length, "0");
|
|
6993
7531
|
/**
|
|
6994
7532
|
* The day a UTC proxy stands for.
|
|
@@ -7154,18 +7692,7 @@ const buildCalendarHeatmapData = (series, options = {}) => {
|
|
|
7154
7692
|
const gridMaxDayKey = widenTo(options.gridSpan?.end, maxDayKey, "later");
|
|
7155
7693
|
const requestedMinDate = civilDate(requestedMinDayKey);
|
|
7156
7694
|
const gridMaxDate = civilDate(gridMaxDayKey);
|
|
7157
|
-
const
|
|
7158
|
-
locale,
|
|
7159
|
-
timeZone: "UTC"
|
|
7160
|
-
};
|
|
7161
|
-
const formatWeekday = createDateFormatter({ weekday: "short" }, labelFormatting);
|
|
7162
|
-
const formatMonth = createDateFormatter({ month: "short" }, labelFormatting);
|
|
7163
|
-
const formatDay = createDateFormatter({
|
|
7164
|
-
weekday: "short",
|
|
7165
|
-
month: "short",
|
|
7166
|
-
day: "numeric",
|
|
7167
|
-
year: "numeric"
|
|
7168
|
-
}, labelFormatting);
|
|
7695
|
+
const { formatWeekday, formatMonth, formatDay } = civilLabelFormatters(locale);
|
|
7169
7696
|
const gridStart = startOfCivilWeek(requestedMinDate, weekStartsOn);
|
|
7170
7697
|
const gridMinDayKey = requestedMinDayKey < minDayKey ? civilKey(gridStart) : requestedMinDayKey;
|
|
7171
7698
|
const weekCount = civilWeekSpan(gridStart, gridMaxDate, weekStartsOn);
|
|
@@ -7206,6 +7733,89 @@ const buildCalendarHeatmapData = (series, options = {}) => {
|
|
|
7206
7733
|
};
|
|
7207
7734
|
};
|
|
7208
7735
|
//#endregion
|
|
7736
|
+
//#region src/charts/heatmap-chart/build-month-calendar-data.ts
|
|
7737
|
+
/** Week rows per month, fixed so every month block is the same height. */
|
|
7738
|
+
const MONTH_ROWS = 6;
|
|
7739
|
+
const DAYS_PER_WEEK = 7;
|
|
7740
|
+
const startOfCivilMonth = (date) => {
|
|
7741
|
+
const first = new Date(date.getTime());
|
|
7742
|
+
first.setUTCDate(1);
|
|
7743
|
+
return first;
|
|
7744
|
+
};
|
|
7745
|
+
const startOfNextCivilMonth = (date) => {
|
|
7746
|
+
const next = startOfCivilMonth(date);
|
|
7747
|
+
next.setUTCMonth(next.getUTCMonth() + 1);
|
|
7748
|
+
return next;
|
|
7749
|
+
};
|
|
7750
|
+
/**
|
|
7751
|
+
* Lay a day-keyed map out as one month calendar per month, weekdays across and
|
|
7752
|
+
* weeks down, for `HeatmapChart` with `columnGroups`.
|
|
7753
|
+
*
|
|
7754
|
+
* @param valueByDay - Value per `yyyy-MM-dd`. A missing day is `null`.
|
|
7755
|
+
* @param range - The measured days; every month from `start`'s through `end`'s is drawn.
|
|
7756
|
+
* @param options - Week start and label locale.
|
|
7757
|
+
* @return Columns and one group per month; empty for an invalid or reversed range.
|
|
7758
|
+
*/
|
|
7759
|
+
const buildMonthCalendarHeatmapData = (valueByDay, range, options = {}) => {
|
|
7760
|
+
const start = civilDate(range.start);
|
|
7761
|
+
const end = civilDate(range.end);
|
|
7762
|
+
if (!start || !end || start.getTime() > end.getTime()) {
|
|
7763
|
+
warnOnce(`heatmap:monthRange:${range.start}:${range.end}`, `range ${JSON.stringify(range)} must be two \`yyyy-MM-dd\` days with start on or before end, so the calendar is empty.`);
|
|
7764
|
+
return {
|
|
7765
|
+
data: [],
|
|
7766
|
+
columnGroups: []
|
|
7767
|
+
};
|
|
7768
|
+
}
|
|
7769
|
+
const startKey = civilKey(start);
|
|
7770
|
+
const endKey = civilKey(end);
|
|
7771
|
+
const weekStartsOn = options.weekStartsOn ?? 1;
|
|
7772
|
+
const { locale } = sanitizeFormatting({ locale: options.locale });
|
|
7773
|
+
for (const key of Object.keys(valueByDay)) if (!civilDate(key)) warnOnce(`heatmap:monthKey:${key}`, `${JSON.stringify(key)} is not a \`yyyy-MM-dd\` day, so its value is left out of the calendar.`);
|
|
7774
|
+
const readValue = (key) => {
|
|
7775
|
+
const value = valueByDay[key];
|
|
7776
|
+
return isPresent(value) ? value : null;
|
|
7777
|
+
};
|
|
7778
|
+
const { formatMonth, formatMonthYear, formatDay } = civilLabelFormatters(locale);
|
|
7779
|
+
const data = [];
|
|
7780
|
+
const columnGroups = [];
|
|
7781
|
+
const lastMonthStart = startOfCivilMonth(end);
|
|
7782
|
+
const formatGroup = (lastMonthStart.getUTCFullYear() - start.getUTCFullYear()) * 12 + lastMonthStart.getUTCMonth() - start.getUTCMonth() + 1 > 12 ? formatMonthYear : formatMonth;
|
|
7783
|
+
for (let monthStart = startOfCivilMonth(start); monthStart.getTime() <= lastMonthStart.getTime(); monthStart = startOfNextCivilMonth(monthStart)) {
|
|
7784
|
+
const monthStartKey = civilKey(monthStart);
|
|
7785
|
+
const monthEndKey = civilKey(addCivilDays(startOfNextCivilMonth(monthStart), -1));
|
|
7786
|
+
const gridStart = startOfCivilWeek(monthStart, weekStartsOn);
|
|
7787
|
+
for (let weekday = 0; weekday < DAYS_PER_WEEK; weekday++) {
|
|
7788
|
+
const cells = [];
|
|
7789
|
+
for (let week = 0; week < MONTH_ROWS; week++) {
|
|
7790
|
+
const day = addCivilDays(gridStart, week * DAYS_PER_WEEK + weekday);
|
|
7791
|
+
const key = civilKey(day);
|
|
7792
|
+
if (key < monthStartKey || key > monthEndKey) cells.push({
|
|
7793
|
+
value: null,
|
|
7794
|
+
hidden: true
|
|
7795
|
+
});
|
|
7796
|
+
else if (key < startKey || key > endKey) cells.push({
|
|
7797
|
+
label: formatDay(day),
|
|
7798
|
+
value: null,
|
|
7799
|
+
placeholder: true
|
|
7800
|
+
});
|
|
7801
|
+
else cells.push({
|
|
7802
|
+
label: formatDay(day),
|
|
7803
|
+
value: readValue(key)
|
|
7804
|
+
});
|
|
7805
|
+
}
|
|
7806
|
+
data.push({ data: cells });
|
|
7807
|
+
}
|
|
7808
|
+
columnGroups.push({
|
|
7809
|
+
label: formatGroup(monthStart),
|
|
7810
|
+
span: DAYS_PER_WEEK
|
|
7811
|
+
});
|
|
7812
|
+
}
|
|
7813
|
+
return {
|
|
7814
|
+
data,
|
|
7815
|
+
columnGroups
|
|
7816
|
+
};
|
|
7817
|
+
};
|
|
7818
|
+
//#endregion
|
|
7209
7819
|
//#region src/charts/heatmap-chart/use-calendar-heatmap-data.ts
|
|
7210
7820
|
/**
|
|
7211
7821
|
* `buildCalendarHeatmapData` with the locale and zone taken from
|
|
@@ -7242,6 +7852,36 @@ const useCalendarHeatmapData = (series, options = {}) => {
|
|
|
7242
7852
|
]);
|
|
7243
7853
|
};
|
|
7244
7854
|
//#endregion
|
|
7855
|
+
//#region src/charts/heatmap-chart/use-month-calendar-heatmap-data.ts
|
|
7856
|
+
/**
|
|
7857
|
+
* `buildMonthCalendarHeatmapData` with the locale taken from `GlobalChartsProvider`
|
|
7858
|
+
* where the caller names none.
|
|
7859
|
+
*
|
|
7860
|
+
* @param valueByDay - Value per `yyyy-MM-dd`. Held by reference, so a caller that rebuilds it each render defeats the memo.
|
|
7861
|
+
* @param range - As for `buildMonthCalendarHeatmapData`.
|
|
7862
|
+
* @param options - As for `buildMonthCalendarHeatmapData`; `locale` wins over the provider.
|
|
7863
|
+
* @return Columns and groups for `HeatmapChart`.
|
|
7864
|
+
*/
|
|
7865
|
+
const useMonthCalendarHeatmapData = (valueByDay, range, options = {}) => {
|
|
7866
|
+
const formatting = useChartFormatting();
|
|
7867
|
+
const locale = options.locale ?? formatting.locale;
|
|
7868
|
+
const { weekStartsOn } = options;
|
|
7869
|
+
const { start, end } = range;
|
|
7870
|
+
return (0, react.useMemo)(() => buildMonthCalendarHeatmapData(valueByDay, {
|
|
7871
|
+
start,
|
|
7872
|
+
end
|
|
7873
|
+
}, {
|
|
7874
|
+
locale,
|
|
7875
|
+
weekStartsOn
|
|
7876
|
+
}), [
|
|
7877
|
+
valueByDay,
|
|
7878
|
+
start,
|
|
7879
|
+
end,
|
|
7880
|
+
locale,
|
|
7881
|
+
weekStartsOn
|
|
7882
|
+
]);
|
|
7883
|
+
};
|
|
7884
|
+
//#endregion
|
|
7245
7885
|
//#region ../../../node_modules/.pnpm/is-plain-object@5.1.0/node_modules/is-plain-object/dist/is-plain-object.mjs
|
|
7246
7886
|
/*!
|
|
7247
7887
|
* is-plain-object <https://github.com/jonschlinkert/is-plain-object>
|
|
@@ -7605,7 +8245,24 @@ var require_dist = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
7605
8245
|
tslib_1.__exportStar(require_dist$1(), exports);
|
|
7606
8246
|
}));
|
|
7607
8247
|
//#endregion
|
|
7608
|
-
//#region ../../../node_modules/.pnpm/@wordpress+
|
|
8248
|
+
//#region ../../../node_modules/.pnpm/@wordpress+warning@3.55.0/node_modules/@wordpress/warning/build-module/utils.mjs
|
|
8249
|
+
var logged = /* @__PURE__ */ new Set();
|
|
8250
|
+
//#endregion
|
|
8251
|
+
//#region ../../../node_modules/.pnpm/@wordpress+warning@3.55.0/node_modules/@wordpress/warning/build-module/index.mjs
|
|
8252
|
+
function isDev() {
|
|
8253
|
+
return globalThis.SCRIPT_DEBUG === true;
|
|
8254
|
+
}
|
|
8255
|
+
function warning(message) {
|
|
8256
|
+
if (!isDev()) return;
|
|
8257
|
+
if (logged.has(message)) return;
|
|
8258
|
+
console.warn(message);
|
|
8259
|
+
try {
|
|
8260
|
+
throw Error(message);
|
|
8261
|
+
} catch {}
|
|
8262
|
+
logged.add(message);
|
|
8263
|
+
}
|
|
8264
|
+
//#endregion
|
|
8265
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@40.1.0_@date-fns+tz@1.5.0_@types+react-dom@18.3.7_@types+react@18_c300d25e93ed6b8d3659e83df7c1508a/node_modules/@wordpress/components/build-module/utils/hooks/use-update-effect.mjs
|
|
7609
8266
|
function useUpdateEffect(effect, deps) {
|
|
7610
8267
|
const mountedRef = (0, react.useRef)(false);
|
|
7611
8268
|
(0, react.useEffect)(() => {
|
|
@@ -9243,7 +9900,7 @@ _createEmotion.css;
|
|
|
9243
9900
|
_createEmotion.sheet;
|
|
9244
9901
|
_createEmotion.cache;
|
|
9245
9902
|
//#endregion
|
|
9246
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@40.
|
|
9903
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@40.1.0_@date-fns+tz@1.5.0_@types+react-dom@18.3.7_@types+react@18_c300d25e93ed6b8d3659e83df7c1508a/node_modules/@wordpress/components/build-module/utils/hooks/use-cx.mjs
|
|
9247
9904
|
var isSerializedStyles = (o) => typeof o !== "undefined" && o !== null && ["name", "styles"].every((p) => typeof o[p] !== "undefined");
|
|
9248
9905
|
var useCx = () => {
|
|
9249
9906
|
const cache = __unsafe_useEmotionCache();
|
|
@@ -9350,7 +10007,7 @@ function memize(fn, options) {
|
|
|
9350
10007
|
return memoized;
|
|
9351
10008
|
}
|
|
9352
10009
|
//#endregion
|
|
9353
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@40.
|
|
10010
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@40.1.0_@date-fns+tz@1.5.0_@types+react-dom@18.3.7_@types+react@18_c300d25e93ed6b8d3659e83df7c1508a/node_modules/@wordpress/components/build-module/utils/colors-values.mjs
|
|
9354
10011
|
var white = "#fff";
|
|
9355
10012
|
var GRAY = {
|
|
9356
10013
|
900: "#1e1e1e",
|
|
@@ -9400,8 +10057,8 @@ var UI = {
|
|
|
9400
10057
|
border: THEME.gray[600],
|
|
9401
10058
|
borderHover: THEME.gray[700],
|
|
9402
10059
|
borderFocus: THEME.accent,
|
|
9403
|
-
borderDisabled:
|
|
9404
|
-
textDisabled:
|
|
10060
|
+
borderDisabled: `var(--wpds-color-stroke-interactive-neutral-disabled, #dbdbdb)`,
|
|
10061
|
+
textDisabled: `var(--wpds-color-foreground-interactive-neutral-disabled, #8d8d8d)`,
|
|
9405
10062
|
darkGrayPlaceholder: `color-mix(in srgb, ${THEME.foreground}, transparent 38%)`,
|
|
9406
10063
|
lightGrayPlaceholder: `color-mix(in srgb, ${THEME.background}, transparent 35%)`
|
|
9407
10064
|
};
|
|
@@ -9429,7 +10086,7 @@ var COLORS = Object.freeze({
|
|
|
9429
10086
|
ui: UI
|
|
9430
10087
|
});
|
|
9431
10088
|
//#endregion
|
|
9432
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@40.
|
|
10089
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@40.1.0_@date-fns+tz@1.5.0_@types+react-dom@18.3.7_@types+react@18_c300d25e93ed6b8d3659e83df7c1508a/node_modules/@wordpress/components/build-module/utils/config-values.mjs
|
|
9433
10090
|
var CONTROL_HEIGHT = "36px";
|
|
9434
10091
|
var CONTROL_PROPS = {
|
|
9435
10092
|
controlPaddingX: 12,
|
|
@@ -9483,8 +10140,8 @@ var config_values_default = Object.assign({}, CONTROL_PROPS, {
|
|
|
9483
10140
|
transitionTimingFunctionControl: "cubic-bezier(0.12, 0.8, 0.32, 1)"
|
|
9484
10141
|
});
|
|
9485
10142
|
//#endregion
|
|
9486
|
-
//#region ../../../node_modules/.pnpm
|
|
9487
|
-
var
|
|
10143
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@40.1.0_@date-fns+tz@1.5.0_@types+react-dom@18.3.7_@types+react@18_c300d25e93ed6b8d3659e83df7c1508a/node_modules/@wordpress/components/build-module/context/context-system-provider.mjs
|
|
10144
|
+
var import_es6 = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
9488
10145
|
module.exports = function equal(a, b) {
|
|
9489
10146
|
if (a === b) return true;
|
|
9490
10147
|
if (a && b && typeof a == "object" && typeof b == "object") {
|
|
@@ -9528,31 +10185,8 @@ var require_es6 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
9528
10185
|
}
|
|
9529
10186
|
return a !== a && b !== b;
|
|
9530
10187
|
};
|
|
9531
|
-
}));
|
|
9532
|
-
|
|
9533
|
-
//#region ../../../node_modules/.pnpm/@wordpress+warning@3.54.0/node_modules/@wordpress/warning/build-module/utils.mjs
|
|
9534
|
-
var logged = /* @__PURE__ */ new Set();
|
|
9535
|
-
//#endregion
|
|
9536
|
-
//#region ../../../node_modules/.pnpm/@wordpress+warning@3.54.0/node_modules/@wordpress/warning/build-module/index.mjs
|
|
9537
|
-
function isDev() {
|
|
9538
|
-
return globalThis.SCRIPT_DEBUG === true;
|
|
9539
|
-
}
|
|
9540
|
-
function warning(message) {
|
|
9541
|
-
if (!isDev()) return;
|
|
9542
|
-
if (logged.has(message)) return;
|
|
9543
|
-
console.warn(message);
|
|
9544
|
-
try {
|
|
9545
|
-
throw Error(message);
|
|
9546
|
-
} catch {}
|
|
9547
|
-
logged.add(message);
|
|
9548
|
-
}
|
|
9549
|
-
//#endregion
|
|
9550
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@40.0.0_@date-fns+tz@1.4.1_@types+react-dom@18.3.7_@types+react@18_4546240ebdf94d561ebf2fde285113fe/node_modules/@wordpress/components/build-module/context/context-system-provider.mjs
|
|
9551
|
-
var import_es6 = /* @__PURE__ */ __toESM(require_es6(), 1);
|
|
9552
|
-
var ComponentsContext = (0, react.createContext)(
|
|
9553
|
-
/** @type {Record<string, any>} */
|
|
9554
|
-
{}
|
|
9555
|
-
);
|
|
10188
|
+
})))(), 1);
|
|
10189
|
+
var ComponentsContext = (0, react.createContext)({});
|
|
9556
10190
|
ComponentsContext.displayName = "ComponentsContext";
|
|
9557
10191
|
var useComponentsContext = () => (0, react.useContext)(ComponentsContext);
|
|
9558
10192
|
function useContextSystemBridge({ value }) {
|
|
@@ -9574,19 +10208,19 @@ var BaseContextSystemProvider = ({ children, value }) => {
|
|
|
9574
10208
|
};
|
|
9575
10209
|
(0, react.memo)(BaseContextSystemProvider);
|
|
9576
10210
|
//#endregion
|
|
9577
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@40.
|
|
10211
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@40.1.0_@date-fns+tz@1.5.0_@types+react-dom@18.3.7_@types+react@18_c300d25e93ed6b8d3659e83df7c1508a/node_modules/@wordpress/components/build-module/context/constants.mjs
|
|
9578
10212
|
var COMPONENT_NAMESPACE = "data-wp-component";
|
|
9579
10213
|
var CONNECTED_NAMESPACE = "data-wp-c16t";
|
|
9580
10214
|
var CONNECT_STATIC_NAMESPACE = "__contextSystemKey__";
|
|
9581
10215
|
//#endregion
|
|
9582
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@40.
|
|
10216
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@40.1.0_@date-fns+tz@1.5.0_@types+react-dom@18.3.7_@types+react@18_c300d25e93ed6b8d3659e83df7c1508a/node_modules/@wordpress/components/build-module/context/get-styled-class-name-from-key.mjs
|
|
9583
10217
|
var import_dist = require_dist();
|
|
9584
10218
|
function getStyledClassName(namespace) {
|
|
9585
10219
|
return `components-${(0, import_dist.paramCase)(namespace)}`;
|
|
9586
10220
|
}
|
|
9587
10221
|
var getStyledClassNameFromKey = memize(getStyledClassName);
|
|
9588
10222
|
//#endregion
|
|
9589
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@40.
|
|
10223
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@40.1.0_@date-fns+tz@1.5.0_@types+react-dom@18.3.7_@types+react@18_c300d25e93ed6b8d3659e83df7c1508a/node_modules/@wordpress/components/build-module/context/context-connect.mjs
|
|
9590
10224
|
function contextConnect(Component, namespace) {
|
|
9591
10225
|
return _contextConnect(Component, namespace, { forwardsRef: true });
|
|
9592
10226
|
}
|
|
@@ -9603,7 +10237,7 @@ function _contextConnect(Component, namespace, options) {
|
|
|
9603
10237
|
});
|
|
9604
10238
|
}
|
|
9605
10239
|
//#endregion
|
|
9606
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@40.
|
|
10240
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@40.1.0_@date-fns+tz@1.5.0_@types+react-dom@18.3.7_@types+react@18_c300d25e93ed6b8d3659e83df7c1508a/node_modules/@wordpress/components/build-module/context/utils.mjs
|
|
9607
10241
|
function getNamespace(componentName) {
|
|
9608
10242
|
return { [COMPONENT_NAMESPACE]: componentName };
|
|
9609
10243
|
}
|
|
@@ -9611,7 +10245,7 @@ function getConnectedNamespace() {
|
|
|
9611
10245
|
return { [CONNECTED_NAMESPACE]: true };
|
|
9612
10246
|
}
|
|
9613
10247
|
//#endregion
|
|
9614
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@40.
|
|
10248
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@40.1.0_@date-fns+tz@1.5.0_@types+react-dom@18.3.7_@types+react@18_c300d25e93ed6b8d3659e83df7c1508a/node_modules/@wordpress/components/build-module/context/use-context-system.mjs
|
|
9615
10249
|
function useContextSystem(props, namespace) {
|
|
9616
10250
|
const contextSystemProps = useComponentsContext();
|
|
9617
10251
|
if (typeof namespace === "undefined") globalThis.SCRIPT_DEBUG === true && warning("useContextSystem: Please provide a namespace");
|
|
@@ -9620,10 +10254,12 @@ function useContextSystem(props, namespace) {
|
|
|
9620
10254
|
...getConnectedNamespace(),
|
|
9621
10255
|
...getNamespace(namespace)
|
|
9622
10256
|
};
|
|
9623
|
-
const { _overrides
|
|
10257
|
+
const { _overrides, ...otherContextProps } = contextProps;
|
|
10258
|
+
const overrideProps = _overrides;
|
|
9624
10259
|
const initialMergedProps = Object.entries(otherContextProps).length ? Object.assign({}, otherContextProps, props) : props;
|
|
10260
|
+
const propsWithChildren = initialMergedProps;
|
|
9625
10261
|
const classes = useCx()(getStyledClassNameFromKey(namespace), props.className);
|
|
9626
|
-
const rendered = typeof
|
|
10262
|
+
const rendered = typeof propsWithChildren.renderChildren === "function" ? propsWithChildren.renderChildren(initialMergedProps) : propsWithChildren.children;
|
|
9627
10263
|
for (const key in initialMergedProps) finalComponentProps[key] = initialMergedProps[key];
|
|
9628
10264
|
for (const key in overrideProps) finalComponentProps[key] = overrideProps[key];
|
|
9629
10265
|
if (rendered !== void 0) finalComponentProps.children = rendered;
|
|
@@ -9631,7 +10267,7 @@ function useContextSystem(props, namespace) {
|
|
|
9631
10267
|
return finalComponentProps;
|
|
9632
10268
|
}
|
|
9633
10269
|
//#endregion
|
|
9634
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@40.
|
|
10270
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@40.1.0_@date-fns+tz@1.5.0_@types+react-dom@18.3.7_@types+react@18_c300d25e93ed6b8d3659e83df7c1508a/node_modules/@wordpress/components/build-module/visually-hidden/styles.mjs
|
|
9635
10271
|
var visuallyHidden = {
|
|
9636
10272
|
border: 0,
|
|
9637
10273
|
clip: "rect(1px, 1px, 1px, 1px)",
|
|
@@ -9647,7 +10283,7 @@ var visuallyHidden = {
|
|
|
9647
10283
|
wordBreak: "normal"
|
|
9648
10284
|
};
|
|
9649
10285
|
//#endregion
|
|
9650
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@40.
|
|
10286
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@40.1.0_@date-fns+tz@1.5.0_@types+react-dom@18.3.7_@types+react@18_c300d25e93ed6b8d3659e83df7c1508a/node_modules/@wordpress/components/build-module/utils/polymorphic-element.mjs
|
|
9651
10287
|
var customAttributeRegExp = /^(data|aria|x)-/i;
|
|
9652
10288
|
var eventHandlerRegExp = /^on[A-Z]/;
|
|
9653
10289
|
var svgElementNames = new Set(`animate animateMotion animateTransform circle clipPath defs desc ellipse
|
|
@@ -9737,7 +10373,7 @@ function UnforwardedPolymorphicElement({ as, ...props }, ref) {
|
|
|
9737
10373
|
}
|
|
9738
10374
|
var PolymorphicElement = (0, react.forwardRef)(UnforwardedPolymorphicElement);
|
|
9739
10375
|
//#endregion
|
|
9740
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@40.
|
|
10376
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@40.1.0_@date-fns+tz@1.5.0_@types+react-dom@18.3.7_@types+react@18_c300d25e93ed6b8d3659e83df7c1508a/node_modules/@wordpress/components/build-module/view/component.mjs
|
|
9741
10377
|
function UnforwardedView({ css, ...restProps }, ref) {
|
|
9742
10378
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PolymorphicElement, {
|
|
9743
10379
|
ref,
|
|
@@ -9746,7 +10382,7 @@ function UnforwardedView({ css, ...restProps }, ref) {
|
|
|
9746
10382
|
}
|
|
9747
10383
|
var component_default$2 = Object.assign((0, react.forwardRef)(UnforwardedView), { selector: ".components-view" });
|
|
9748
10384
|
//#endregion
|
|
9749
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@40.
|
|
10385
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@40.1.0_@date-fns+tz@1.5.0_@types+react-dom@18.3.7_@types+react@18_c300d25e93ed6b8d3659e83df7c1508a/node_modules/@wordpress/components/build-module/visually-hidden/component.mjs
|
|
9750
10386
|
function UnconnectedVisuallyHidden(props, forwardedRef) {
|
|
9751
10387
|
const { style: styleProp, ...contextProps } = useContextSystem(props, "VisuallyHidden");
|
|
9752
10388
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(component_default$2, {
|
|
@@ -9761,7 +10397,7 @@ function UnconnectedVisuallyHidden(props, forwardedRef) {
|
|
|
9761
10397
|
}
|
|
9762
10398
|
var component_default$1 = contextConnect(UnconnectedVisuallyHidden, "VisuallyHidden");
|
|
9763
10399
|
//#endregion
|
|
9764
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@40.
|
|
10400
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@40.1.0_@date-fns+tz@1.5.0_@types+react-dom@18.3.7_@types+react@18_c300d25e93ed6b8d3659e83df7c1508a/node_modules/@wordpress/components/build-module/utils/use-responsive-value.mjs
|
|
9765
10401
|
var breakpoints = [
|
|
9766
10402
|
"40em",
|
|
9767
10403
|
"52em",
|
|
@@ -9795,7 +10431,7 @@ function useResponsiveValue(values, options = {}) {
|
|
|
9795
10431
|
return array[index >= array.length ? array.length - 1 : index];
|
|
9796
10432
|
}
|
|
9797
10433
|
//#endregion
|
|
9798
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@40.
|
|
10434
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@40.1.0_@date-fns+tz@1.5.0_@types+react-dom@18.3.7_@types+react@18_c300d25e93ed6b8d3659e83df7c1508a/node_modules/@wordpress/components/build-module/grid/utils.mjs
|
|
9799
10435
|
var ALIGNMENTS = {
|
|
9800
10436
|
bottom: {
|
|
9801
10437
|
alignItems: "flex-end",
|
|
@@ -9843,7 +10479,7 @@ function getAlignmentProps(alignment) {
|
|
|
9843
10479
|
return alignment ? ALIGNMENTS[alignment] : {};
|
|
9844
10480
|
}
|
|
9845
10481
|
//#endregion
|
|
9846
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@40.
|
|
10482
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@40.1.0_@date-fns+tz@1.5.0_@types+react-dom@18.3.7_@types+react@18_c300d25e93ed6b8d3659e83df7c1508a/node_modules/@wordpress/components/build-module/grid/hook.mjs
|
|
9847
10483
|
function useGrid(props) {
|
|
9848
10484
|
const { align, alignment, className, columnGap, columns = 2, gap = 3, isInline = false, justify, rowGap, rows, templateColumns, templateRows, ...otherProps } = useContextSystem(props, "Grid");
|
|
9849
10485
|
const column = useResponsiveValue(Array.isArray(columns) ? columns : [columns]);
|
|
@@ -9885,7 +10521,7 @@ function useGrid(props) {
|
|
|
9885
10521
|
};
|
|
9886
10522
|
}
|
|
9887
10523
|
//#endregion
|
|
9888
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@40.
|
|
10524
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@40.1.0_@date-fns+tz@1.5.0_@types+react-dom@18.3.7_@types+react@18_c300d25e93ed6b8d3659e83df7c1508a/node_modules/@wordpress/components/build-module/grid/component.mjs
|
|
9889
10525
|
function UnconnectedGrid(props, forwardedRef) {
|
|
9890
10526
|
const gridProps = useGrid(props);
|
|
9891
10527
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(component_default$2, {
|
|
@@ -11171,6 +11807,7 @@ exports.SparklineUnresponsive = SparklineUnresponsive;
|
|
|
11171
11807
|
exports.ThemeProvider = GlobalChartsProvider;
|
|
11172
11808
|
exports.TrendIndicator = TrendIndicator;
|
|
11173
11809
|
exports.buildCalendarHeatmapData = buildCalendarHeatmapData;
|
|
11810
|
+
exports.buildMonthCalendarHeatmapData = buildMonthCalendarHeatmapData;
|
|
11174
11811
|
exports.defaultTheme = defaultTheme;
|
|
11175
11812
|
exports.formatMetricValue = formatMetricValue;
|
|
11176
11813
|
exports.formatPercentage = formatPercentage;
|
|
@@ -11195,6 +11832,7 @@ exports.useChartScopeElement = useChartScopeElement;
|
|
|
11195
11832
|
exports.useGlobalChartsContext = useGlobalChartsContext;
|
|
11196
11833
|
exports.useGlobalChartsTheme = useGlobalChartsTheme;
|
|
11197
11834
|
exports.useLeaderboardLegendItems = useLeaderboardLegendItems;
|
|
11835
|
+
exports.useMonthCalendarHeatmapData = useMonthCalendarHeatmapData;
|
|
11198
11836
|
exports.validateHexColor = validateHexColor;
|
|
11199
11837
|
|
|
11200
11838
|
//# sourceMappingURL=index.cjs.map
|