@automattic/charts 1.12.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/TOKENS.md +8 -1
  3. package/dist/index.cjs +2487 -3465
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.css +15 -18
  6. package/dist/index.d.cts +15 -1
  7. package/dist/index.d.ts +15 -1
  8. package/dist/index.js +452 -1429
  9. package/dist/index.js.map +1 -1
  10. package/package.json +5 -5
  11. package/src/charts/area-chart/area-chart.tsx +6 -7
  12. package/src/charts/bar-chart/bar-chart.tsx +24 -15
  13. package/src/charts/bar-chart/private/use-bar-chart-options.ts +197 -30
  14. package/src/charts/bar-chart/test/bar-chart.test.tsx +685 -1
  15. package/src/charts/conversion-funnel-chart/conversion-funnel-chart.module.scss +7 -7
  16. package/src/charts/line-chart/line-chart.module.scss +3 -3
  17. package/src/charts/line-chart/line-chart.tsx +6 -7
  18. package/src/charts/line-chart/test/line-chart.test.tsx +44 -4
  19. package/src/charts/pie-semi-circle-chart/pie-semi-circle-chart.module.scss +1 -1
  20. package/src/charts/private/test/time-axis.test.ts +427 -0
  21. package/src/charts/private/time-axis.ts +291 -23
  22. package/src/charts/private/x-zoom/test/x-zoom.test.tsx +52 -7
  23. package/src/charts/private/x-zoom/x-zoom.module.scss +7 -15
  24. package/src/charts/private/x-zoom/x-zoom.tsx +29 -40
  25. package/src/components/legend/private/base-legend.module.scss +1 -1
  26. package/src/components/legend/test/legend.test.tsx +2 -1
  27. package/src/components/tooltip/base-tooltip.module.scss +1 -1
  28. package/src/components/trend-indicator/test/trend-indicator.test.tsx +2 -1
  29. package/src/components/trend-indicator/trend-indicator.module.scss +1 -1
  30. package/src/hooks/test/use-chart-margin.test.tsx +60 -0
  31. package/src/hooks/test/use-xychart-theme-style-reads.test.tsx +83 -0
  32. package/src/hooks/use-chart-margin.tsx +3 -4
  33. package/src/hooks/use-xychart-theme.ts +17 -11
  34. package/src/index.ts +1 -0
  35. package/src/types.ts +15 -0
  36. package/src/utils/index.ts +1 -1
  37. package/src/utils/resolve-css-var.ts +69 -28
  38. package/src/utils/test/create-css-variable-resolver.test.ts +83 -0
package/dist/index.js CHANGED
@@ -14,8 +14,7 @@ import { useTooltip, useTooltipInPortal } from "@visx/tooltip";
14
14
  import { createScale, getTicks, scaleBand, scaleOrdinal, scaleTime } from "@visx/scale";
15
15
  import { Group } from "@visx/group";
16
16
  import { LegendItem, LegendLabel, LegendOrdinal, LegendShape } from "@visx/legend";
17
- import { __assign } from "tslib";
18
- import { Icon, chevronRight } from "@wordpress/icons";
17
+ import { IconButton, Stack, Text as Text$1 } from "@wordpress/ui";
19
18
  import { LinearGradient } from "@visx/gradient";
20
19
  import { curveCatmullRom, curveLinear, curveMonotoneX } from "@visx/curve";
21
20
  import { useParentSize } from "@visx/responsive";
@@ -23,8 +22,10 @@ import { Annotation, CircleSubject, Connector, HtmlLabel, Label, LineSubject } f
23
22
  import { PatternCircles, PatternHexagons, PatternLines, PatternWaves } from "@visx/pattern";
24
23
  import { Chart } from "react-google-charts";
25
24
  import DOMPurify from "dompurify";
25
+ import { __assign } from "tslib";
26
26
  import "@babel/runtime/helpers/esm/extends";
27
27
  import "@babel/runtime/helpers/extends";
28
+ import { Icon, chevronRight } from "@wordpress/icons";
28
29
  import { Pie } from "@visx/shape";
29
30
  //#region \0rolldown/runtime.js
30
31
  var __create = Object.create;
@@ -507,15 +508,31 @@ const CSS_VAR_NAME_PATTERN = /^--[\w-]+$/;
507
508
  * @param element - Optional DOM element to resolve the variable from (defaults to document.documentElement)
508
509
  * @return The resolved value, fallback value, or null if unresolvable
509
510
  */
510
- const resolveCssVariable = (value, element) => {
511
- if (!value) return null;
512
- if (value.startsWith("var(") && value.endsWith(")")) {
513
- const parsed = parseVarExpression(value);
514
- if (parsed) return resolveVariableName(parsed.varName, element) || parsed.fallback;
515
- }
516
- if (value.startsWith("--")) return resolveVariableName(value, element);
517
- return value;
518
- };
511
+ const resolveCssVariable = (value, element) => createCssVariableResolver(element)(value);
512
+ /**
513
+ * Builds a resolver that reads every value from one `getComputedStyle` snapshot.
514
+ *
515
+ * `getComputedStyle` is the expensive half of resolving a token: each call can force the browser to flush pending style, and a chart theme resolves five roles at once. Taking the snapshot once per build turns that into a single query. The reads that share a snapshot happen synchronously inside one memo body, so no style change can land between them — the resolver is single-pass by design and is not meant to be held across renders.
516
+ *
517
+ * @param element - The element to resolve against, or null/undefined for the document root.
518
+ * @return A resolver that resolves each value exactly as `resolveCssVariable` does.
519
+ */
520
+ function createCssVariableResolver(element) {
521
+ let styles = null;
522
+ const getStyles = () => {
523
+ if (!styles) styles = computedStyleFor(element);
524
+ return styles;
525
+ };
526
+ return (value) => {
527
+ if (!value) return null;
528
+ if (value.startsWith("var(") && value.endsWith(")")) {
529
+ const parsed = parseVarExpression(value);
530
+ if (parsed) return readCustomProperty(parsed.varName, getStyles()) || parsed.fallback;
531
+ }
532
+ if (value.startsWith("--")) return readCustomProperty(value, getStyles());
533
+ return value;
534
+ };
535
+ }
519
536
  /**
520
537
  * Parses a var() expression into its variable name and optional fallback.
521
538
  * Uses string manipulation instead of complex regex to avoid ReDoS.
@@ -543,17 +560,30 @@ function parseVarExpression(expr) {
543
560
  };
544
561
  }
545
562
  /**
546
- * Resolves a plain CSS variable name to its computed value.
563
+ * Takes one computed-style snapshot, or null where there is nothing to read (SSR, or a detached element).
564
+ *
565
+ * @param element - The element to read from, or null/undefined for the document root.
566
+ * @return The computed styles, or null.
567
+ */
568
+ function computedStyleFor(element) {
569
+ if (typeof window === "undefined" || typeof document === "undefined") return null;
570
+ try {
571
+ return getComputedStyle(element || document.documentElement);
572
+ } catch {
573
+ return null;
574
+ }
575
+ }
576
+ /**
577
+ * Reads one custom property from a computed-style snapshot.
547
578
  *
548
579
  * @param varName - A CSS variable name like '--my-color'
549
- * @param element - Optional DOM element to resolve from
580
+ * @param styles - The snapshot to read from, or null
550
581
  * @return The computed value or null
551
582
  */
552
- function resolveVariableName(varName, element) {
553
- if (typeof window === "undefined" || typeof document === "undefined") return null;
583
+ function readCustomProperty(varName, styles) {
584
+ if (!styles) return null;
554
585
  try {
555
- const targetElement = element || document.documentElement;
556
- return getComputedStyle(targetElement).getPropertyValue(varName).trim() || null;
586
+ return styles.getPropertyValue(varName).trim() || null;
557
587
  } catch {
558
588
  return null;
559
589
  }
@@ -1022,11 +1052,13 @@ const useDeepMemo = (value) => {
1022
1052
  };
1023
1053
  //#endregion
1024
1054
  //#region src/hooks/use-xychart-theme.ts
1025
- const resolveColor = (value) => value ? resolveCssVariable(value) ?? value : value;
1026
1055
  const useXYChartTheme = (data) => {
1027
1056
  const theme = useGlobalChartsTheme();
1057
+ const seriesColorKey = JSON.stringify((data ?? []).map((series) => series.options?.stroke).filter((color) => Boolean(color)));
1028
1058
  return useMemo(() => {
1029
- const seriesColors = (data ?? []).map((series) => series.options?.stroke).filter((color) => Boolean(color));
1059
+ const resolve = createCssVariableResolver();
1060
+ const resolveColor = (value) => value ? resolve(value) ?? value : value;
1061
+ const seriesColors = JSON.parse(seriesColorKey);
1030
1062
  return buildChartTheme({
1031
1063
  ...theme,
1032
1064
  colors: [...seriesColors, ...theme.colors ?? []],
@@ -1048,7 +1080,7 @@ const useXYChartTheme = (data) => {
1048
1080
  fill: resolveColor(theme.svgLabelSmall.fill)
1049
1081
  }
1050
1082
  });
1051
- }, [theme, data]);
1083
+ }, [theme, seriesColorKey]);
1052
1084
  };
1053
1085
  //#endregion
1054
1086
  //#region src/hooks/use-chart-data-transform.ts
@@ -1135,7 +1167,7 @@ const getXAxisLabelMetrics = (theme, orientation) => {
1135
1167
  const useChartMargin = (height, options, data, theme, horizontal = false) => {
1136
1168
  const yTicks = useMemo(() => {
1137
1169
  const allDataPoints = data.flatMap((series) => series.data);
1138
- if (horizontal) return allDataPoints.map((d) => d.label || options.axis?.y?.tickFormat(d.date.getTime(), 0, []));
1170
+ if (horizontal) return allDataPoints.map((d) => d.label || d.date?.getTime());
1139
1171
  if (options.axis?.y?.tickValues?.length) return options.axis.y.tickValues;
1140
1172
  const minY = Math.min(...allDataPoints.map((d) => d.value));
1141
1173
  const maxY = Math.max(...allDataPoints.map((d) => d.value));
@@ -1375,1336 +1407,80 @@ const useInteractiveLegendData = ({ data, chartId, legendInteractive, isSeriesVi
1375
1407
  ]);
1376
1408
  return {
1377
1409
  visibleData,
1378
- allSegmentsHidden: useMemo(() => {
1379
- return legendInteractive && visibleData.length === 0;
1380
- }, [legendInteractive, visibleData]),
1381
- legendData: useMemo(() => {
1382
- if (!legendInteractive || !chartId) return data;
1383
- const visibleDataMap = new Map(visibleData.map((d) => [d.label, d]));
1384
- return data.map((segment) => {
1385
- if (!isSeriesVisible(chartId, segment.label)) return segment;
1386
- return visibleDataMap.get(segment.label) || segment;
1387
- });
1388
- }, [
1389
- data,
1390
- visibleData,
1391
- legendInteractive,
1392
- chartId,
1393
- isSeriesVisible
1394
- ])
1395
- };
1396
- };
1397
- //#endregion
1398
- //#region src/hooks/use-prefers-reduced-motion.ts
1399
- const QUERY = "(prefers-reduced-motion: no-preference)";
1400
- const getInitialState = () => !window.matchMedia(QUERY).matches;
1401
- /**
1402
- * Custom hook to determine if the user prefers reduced motion.
1403
- * @return {boolean} A boolean indicating the user's preference for reduced motion.
1404
- */
1405
- function usePrefersReducedMotion() {
1406
- const [prefersReducedMotion, setPrefersReducedMotion] = useState(getInitialState);
1407
- useEffect(() => {
1408
- const mediaQueryList = window.matchMedia(QUERY);
1409
- const listener = (event) => {
1410
- setPrefersReducedMotion(!event.matches);
1411
- };
1412
- mediaQueryList.addEventListener("change", listener);
1413
- return () => {
1414
- mediaQueryList.removeEventListener("change", listener);
1415
- };
1416
- }, []);
1417
- return prefersReducedMotion;
1418
- }
1419
- //#endregion
1420
- //#region src/providers/chart-context/hooks/use-chart-registration.ts
1421
- const useChartRegistration = ({ chartId, legendItems, chartType, isDataValid, metadata }) => {
1422
- const { registerChart, unregisterChart } = useGlobalChartsContext();
1423
- const stableLegendItems = useDeepMemo(legendItems);
1424
- const memoizedMetadata = useMemo(() => metadata, [metadata]);
1425
- useEffect(() => {
1426
- if (isDataValid) registerChart(chartId, {
1427
- legendItems: stableLegendItems,
1428
- chartType,
1429
- metadata: memoizedMetadata
1430
- });
1431
- return () => {
1432
- unregisterChart(chartId);
1433
- };
1434
- }, [
1435
- chartId,
1436
- stableLegendItems,
1437
- chartType,
1438
- memoizedMetadata,
1439
- isDataValid
1440
- ]);
1441
- };
1442
- //#endregion
1443
- //#region src/providers/chart-context/hooks/use-global-charts-theme.ts
1444
- /**
1445
- * Hook to get the global chart theme from GlobalChartsProvider
1446
- *
1447
- * @return The global chart theme
1448
- */
1449
- const useGlobalChartsTheme = () => {
1450
- return useContext(GlobalChartsContext)?.theme ?? defaultTheme;
1451
- };
1452
- //#endregion
1453
- //#region ../../../node_modules/.pnpm/is-plain-object@5.0.0/node_modules/is-plain-object/dist/is-plain-object.mjs
1454
- /*!
1455
- * is-plain-object <https://github.com/jonschlinkert/is-plain-object>
1456
- *
1457
- * Copyright (c) 2014-2017, Jon Schlinkert.
1458
- * Released under the MIT License.
1459
- */
1460
- function isObject(o) {
1461
- return Object.prototype.toString.call(o) === "[object Object]";
1462
- }
1463
- function isPlainObject(o) {
1464
- var ctor, prot;
1465
- if (isObject(o) === false) return false;
1466
- ctor = o.constructor;
1467
- if (ctor === void 0) return true;
1468
- prot = ctor.prototype;
1469
- if (isObject(prot) === false) return false;
1470
- if (prot.hasOwnProperty("isPrototypeOf") === false) return false;
1471
- return true;
1472
- }
1473
- //#endregion
1474
- //#region ../../../node_modules/.pnpm/lower-case@2.0.2/node_modules/lower-case/dist.es2015/index.js
1475
- /**
1476
- * Lower case as a function.
1477
- */
1478
- function lowerCase(str) {
1479
- return str.toLowerCase();
1480
- }
1481
- //#endregion
1482
- //#region ../../../node_modules/.pnpm/no-case@3.0.4/node_modules/no-case/dist.es2015/index.js
1483
- var DEFAULT_SPLIT_REGEXP = [/([a-z0-9])([A-Z])/g, /([A-Z])([A-Z][a-z])/g];
1484
- var DEFAULT_STRIP_REGEXP = /[^A-Z0-9]+/gi;
1485
- /**
1486
- * Normalize the string into something other libraries can manipulate easier.
1487
- */
1488
- function noCase(input, options) {
1489
- if (options === void 0) options = {};
1490
- var _a = options.splitRegexp, splitRegexp = _a === void 0 ? DEFAULT_SPLIT_REGEXP : _a, _b = options.stripRegexp, stripRegexp = _b === void 0 ? DEFAULT_STRIP_REGEXP : _b, _c = options.transform, transform = _c === void 0 ? lowerCase : _c, _d = options.delimiter, delimiter = _d === void 0 ? " " : _d;
1491
- var result = replace$1(replace$1(input, splitRegexp, "$1\0$2"), stripRegexp, "\0");
1492
- var start = 0;
1493
- var end = result.length;
1494
- while (result.charAt(start) === "\0") start++;
1495
- while (result.charAt(end - 1) === "\0") end--;
1496
- return result.slice(start, end).split("\0").map(transform).join(delimiter);
1497
- }
1498
- /**
1499
- * Replace `re` in the input string with the replacement value.
1500
- */
1501
- function replace$1(input, re, value) {
1502
- if (re instanceof RegExp) return input.replace(re, value);
1503
- return re.reduce(function(input, re) {
1504
- return input.replace(re, value);
1505
- }, input);
1506
- }
1507
- //#endregion
1508
- //#region ../../../node_modules/.pnpm/dot-case@3.0.4/node_modules/dot-case/dist.es2015/index.js
1509
- function dotCase(input, options) {
1510
- if (options === void 0) options = {};
1511
- return noCase(input, __assign({ delimiter: "." }, options));
1512
- }
1513
- //#endregion
1514
- //#region ../../../node_modules/.pnpm/param-case@3.0.4/node_modules/param-case/dist.es2015/index.js
1515
- function paramCase(input, options) {
1516
- if (options === void 0) options = {};
1517
- return dotCase(input, __assign({ delimiter: "-" }, options));
1518
- }
1519
- //#endregion
1520
- //#region ../../../node_modules/.pnpm/@base-ui+utils@0.3.1_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@base-ui/utils/error.mjs
1521
- let set$1;
1522
- if (process.env.NODE_ENV !== "production") set$1 = /* @__PURE__ */ new Set();
1523
- function error(...messages) {
1524
- if (process.env.NODE_ENV !== "production") {
1525
- const messageKey = messages.join(" ");
1526
- if (!set$1.has(messageKey)) {
1527
- set$1.add(messageKey);
1528
- console.error(`Base UI: ${messageKey}`);
1529
- }
1530
- }
1531
- }
1532
- //#endregion
1533
- //#region ../../../node_modules/.pnpm/@base-ui+utils@0.3.1_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@base-ui/utils/safeReact.mjs
1534
- /**
1535
- * A clone of the React namespace for reading APIs that may be missing in older
1536
- * supported React versions. Bundlers can rewrite direct `React.someNewApi`
1537
- * reads into named imports, which breaks React 17. Reading from this cloned
1538
- * object keeps those lookups optional.
1539
- *
1540
- * @see https://github.com/mui/material-ui/issues/41190#issuecomment-2040873379
1541
- */
1542
- const SafeReact = { ...React };
1543
- //#endregion
1544
- //#region ../../../node_modules/.pnpm/@base-ui+utils@0.3.1_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@base-ui/utils/useRefWithInit.mjs
1545
- const UNINITIALIZED = {};
1546
- /**
1547
- * A React.useRef() that is initialized with a function. Note that it accepts an optional
1548
- * initialization argument, so the initialization function doesn't need to be an inline closure.
1549
- *
1550
- * @usage
1551
- * const ref = useRefWithInit(sortColumns, columns)
1552
- */
1553
- function useRefWithInit(init, initArg) {
1554
- const ref = React.useRef(UNINITIALIZED);
1555
- if (ref.current === UNINITIALIZED) ref.current = init(initArg);
1556
- return ref;
1557
- }
1558
- //#endregion
1559
- //#region ../../../node_modules/.pnpm/@base-ui+utils@0.3.1_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@base-ui/utils/useStableCallback.mjs
1560
- const useInsertionEffect$1 = SafeReact.useInsertionEffect;
1561
- const useSafeInsertionEffect = useInsertionEffect$1 && useInsertionEffect$1 !== SafeReact.useLayoutEffect ? useInsertionEffect$1 : (fn) => fn();
1562
- /**
1563
- * Stabilizes the function passed so it's always the same between renders.
1564
- *
1565
- * The function becomes non-reactive to any values it captures.
1566
- * It can safely be passed as a dependency of `React.useMemo` and `React.useEffect` without re-triggering them if its captured values change.
1567
- *
1568
- * The function must only be called inside effects and event handlers, never during render (which throws an error).
1569
- *
1570
- * This hook is a more permissive version of React 19.2's `React.useEffectEvent` in that it can be passed through contexts and called in event handler props, not just effects.
1571
- */
1572
- function useStableCallback(callback) {
1573
- const stable = useRefWithInit(createStableCallback).current;
1574
- stable.next = callback;
1575
- useSafeInsertionEffect(stable.effect);
1576
- return stable.trampoline;
1577
- }
1578
- function createStableCallback() {
1579
- const stable = {
1580
- next: void 0,
1581
- callback: assertNotCalled,
1582
- trampoline: (...args) => stable.callback?.(...args),
1583
- effect: () => {
1584
- stable.callback = stable.next;
1585
- }
1586
- };
1587
- return stable;
1588
- }
1589
- function assertNotCalled() {
1590
- if (process.env.NODE_ENV !== "production") throw new Error("Base UI: Cannot call an event handler while rendering.");
1591
- }
1592
- //#endregion
1593
- //#region ../../../node_modules/.pnpm/@base-ui+utils@0.3.1_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@base-ui/utils/useIsoLayoutEffect.mjs
1594
- const noop = () => {};
1595
- const useIsoLayoutEffect = typeof document !== "undefined" ? React.useLayoutEffect : noop;
1596
- //#endregion
1597
- //#region ../../../node_modules/.pnpm/@base-ui+utils@0.3.1_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@base-ui/utils/warn.mjs
1598
- let set;
1599
- if (process.env.NODE_ENV !== "production") set = /* @__PURE__ */ new Set();
1600
- function warn(...messages) {
1601
- if (process.env.NODE_ENV !== "production") {
1602
- const messageKey = messages.join(" ");
1603
- if (!set.has(messageKey)) {
1604
- set.add(messageKey);
1605
- console.warn(`Base UI: ${messageKey}`);
1606
- }
1607
- }
1608
- }
1609
- //#endregion
1610
- //#region ../../../node_modules/.pnpm/@base-ui+utils@0.3.1_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@base-ui/utils/formatErrorMessage.mjs
1611
- /**
1612
- * Creates a formatErrorMessage function with a custom URL and prefix.
1613
- * @param baseUrl - The base URL for the error page (e.g., 'https://base-ui.com/production-error')
1614
- * @param prefix - The prefix for the error message (e.g., 'Base UI')
1615
- * @returns A function that formats error messages with the given URL and prefix
1616
- */
1617
- function createFormatErrorMessage(baseUrl, prefix) {
1618
- return function formatErrorMessage(code, ...args) {
1619
- const url = new URL(baseUrl);
1620
- url.searchParams.set("code", code.toString());
1621
- args.forEach((arg) => url.searchParams.append("args[]", arg));
1622
- return `${prefix} error #${code}; visit ${url} for the full message.`;
1623
- };
1624
- }
1625
- /**
1626
- * WARNING: Don't import this directly. It's imported by the code generated by
1627
- * `@mui/internal-babel-plugin-minify-errors`. Make sure to always use string literals in `Error`
1628
- * constructors to ensure the plugin works as expected. Supported patterns include:
1629
- * throw new Error('My message');
1630
- * throw new Error(`My message: ${foo}`);
1631
- * throw new Error(`My message: ${foo}` + 'another string');
1632
- * ...
1633
- */
1634
- const formatErrorMessage = createFormatErrorMessage("https://base-ui.com/production-error", "Base UI");
1635
- //#endregion
1636
- //#region ../../../node_modules/.pnpm/@base-ui+utils@0.3.1_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@base-ui/utils/useMergedRefs.mjs
1637
- /**
1638
- * Merges refs into a single memoized callback ref or `null`.
1639
- * This makes sure multiple refs are updated together and have the same value.
1640
- *
1641
- * This function accepts up to four refs. If you need to merge more, or have an unspecified number of refs to merge,
1642
- * use `useMergedRefsN` instead.
1643
- */
1644
- function useMergedRefs(a, b, c, d) {
1645
- const forkRef = useRefWithInit(createForkRef).current;
1646
- if (didChange(forkRef, a, b, c, d)) update(forkRef, [
1647
- a,
1648
- b,
1649
- c,
1650
- d
1651
- ]);
1652
- return forkRef.callback;
1653
- }
1654
- /**
1655
- * Merges an array of refs into a single memoized callback ref or `null`.
1656
- *
1657
- * If you need to merge a fixed number (up to four) of refs, use `useMergedRefs` instead for better performance.
1658
- */
1659
- function useMergedRefsN(refs) {
1660
- const forkRef = useRefWithInit(createForkRef).current;
1661
- if (didChangeN(forkRef, refs)) update(forkRef, refs);
1662
- return forkRef.callback;
1663
- }
1664
- function createForkRef() {
1665
- return {
1666
- callback: null,
1667
- cleanup: null,
1668
- refs: []
1669
- };
1670
- }
1671
- function didChange(forkRef, a, b, c, d) {
1672
- return forkRef.refs[0] !== a || forkRef.refs[1] !== b || forkRef.refs[2] !== c || forkRef.refs[3] !== d;
1673
- }
1674
- function didChangeN(forkRef, newRefs) {
1675
- return forkRef.refs.length !== newRefs.length || forkRef.refs.some((ref, index) => ref !== newRefs[index]);
1676
- }
1677
- function update(forkRef, refs) {
1678
- forkRef.refs = refs;
1679
- if (refs.every((ref) => ref == null)) {
1680
- forkRef.callback = null;
1681
- return;
1682
- }
1683
- forkRef.callback = (instance) => {
1684
- if (forkRef.cleanup) {
1685
- forkRef.cleanup();
1686
- forkRef.cleanup = null;
1687
- }
1688
- if (instance != null) {
1689
- const cleanupCallbacks = Array(refs.length).fill(null);
1690
- for (let i = 0; i < refs.length; i += 1) {
1691
- const ref = refs[i];
1692
- if (ref == null) continue;
1693
- switch (typeof ref) {
1694
- case "function": {
1695
- const refCleanup = ref(instance);
1696
- if (typeof refCleanup === "function") cleanupCallbacks[i] = refCleanup;
1697
- break;
1698
- }
1699
- case "object":
1700
- ref.current = instance;
1701
- break;
1702
- default:
1703
- }
1704
- }
1705
- forkRef.cleanup = () => {
1706
- for (let i = 0; i < refs.length; i += 1) {
1707
- const ref = refs[i];
1708
- if (ref == null) continue;
1709
- switch (typeof ref) {
1710
- case "function": {
1711
- const cleanupCallback = cleanupCallbacks[i];
1712
- if (typeof cleanupCallback === "function") cleanupCallback();
1713
- else ref(null);
1714
- break;
1715
- }
1716
- case "object":
1717
- ref.current = null;
1718
- break;
1719
- default:
1720
- }
1721
- }
1722
- };
1723
- }
1724
- };
1725
- }
1726
- //#endregion
1727
- //#region ../../../node_modules/.pnpm/@base-ui+utils@0.3.1_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@base-ui/utils/reactVersion.mjs
1728
- const majorVersion = parseInt(React.version, 10);
1729
- function isReactVersionAtLeast(reactVersionToCheck) {
1730
- return majorVersion >= reactVersionToCheck;
1731
- }
1732
- //#endregion
1733
- //#region ../../../node_modules/.pnpm/@base-ui+utils@0.3.1_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@base-ui/utils/getReactElementRef.mjs
1734
- /**
1735
- * Extracts the `ref` from a React element, handling different React versions.
1736
- */
1737
- function getReactElementRef(element) {
1738
- if (!/*#__PURE__*/ React.isValidElement(element)) return null;
1739
- const reactElement = element;
1740
- const propsWithRef = reactElement.props;
1741
- return (isReactVersionAtLeast(19) ? propsWithRef?.ref : reactElement.ref) ?? null;
1742
- }
1743
- //#endregion
1744
- //#region ../../../node_modules/.pnpm/@base-ui+utils@0.3.1_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@base-ui/utils/mergeObjects.mjs
1745
- function mergeObjects(a, b) {
1746
- if (a && !b) return a;
1747
- if (!a && b) return b;
1748
- if (a || b) return {
1749
- ...a,
1750
- ...b
1751
- };
1752
- }
1753
- Object.freeze([]);
1754
- const EMPTY_OBJECT = Object.freeze({});
1755
- //#endregion
1756
- //#region ../../../node_modules/.pnpm/@base-ui+react@1.6.0_@types+react@18.3.28_date-fns@4.1.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@base-ui/react/internals/getStateAttributesProps.mjs
1757
- function getStateAttributesProps(state, customMapping) {
1758
- const props = {};
1759
- for (const key in state) {
1760
- const value = state[key];
1761
- if (customMapping?.hasOwnProperty(key)) {
1762
- const customProps = customMapping[key](value);
1763
- if (customProps != null) Object.assign(props, customProps);
1764
- continue;
1765
- }
1766
- if (value === true) props[`data-${key.toLowerCase()}`] = "";
1767
- else if (value) props[`data-${key.toLowerCase()}`] = value.toString();
1768
- }
1769
- return props;
1770
- }
1771
- //#endregion
1772
- //#region ../../../node_modules/.pnpm/@base-ui+react@1.6.0_@types+react@18.3.28_date-fns@4.1.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@base-ui/react/utils/resolveClassName.mjs
1773
- /**
1774
- * If the provided className is a string, it will be returned as is.
1775
- * Otherwise, the function will call the className function with the state as the first argument.
1776
- *
1777
- * @param className
1778
- * @param state
1779
- */
1780
- function resolveClassName(className, state) {
1781
- return typeof className === "function" ? className(state) : className;
1782
- }
1783
- //#endregion
1784
- //#region ../../../node_modules/.pnpm/@base-ui+react@1.6.0_@types+react@18.3.28_date-fns@4.1.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@base-ui/react/utils/resolveStyle.mjs
1785
- /**
1786
- * If the provided style is an object, it will be returned as is.
1787
- * Otherwise, the function will call the style function with the state as the first argument.
1788
- *
1789
- * @param style
1790
- * @param state
1791
- */
1792
- function resolveStyle(style, state) {
1793
- return typeof style === "function" ? style(state) : style;
1794
- }
1795
- //#endregion
1796
- //#region ../../../node_modules/.pnpm/@base-ui+react@1.6.0_@types+react@18.3.28_date-fns@4.1.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@base-ui/react/merge-props/mergeProps.mjs
1797
- const EMPTY_PROPS = {};
1798
- /**
1799
- * Merges multiple sets of React props. It follows the Object.assign pattern where the rightmost object's fields overwrite
1800
- * the conflicting ones from others. This doesn't apply to event handlers, `className` and `style` props.
1801
- *
1802
- * Event handlers are merged and called in right-to-left order (rightmost handler executes first, leftmost last).
1803
- * For React synthetic events, the rightmost handler can prevent prior (left-positioned) handlers from executing
1804
- * by calling `event.preventBaseUIHandler()`. For non-synthetic events (custom events with primitive/object values),
1805
- * all handlers always execute without prevention capability.
1806
- *
1807
- * The `className` prop is merged by concatenating classes in right-to-left order (rightmost class appears first in the string).
1808
- * The `style` prop is merged with rightmost styles overwriting the prior ones.
1809
- *
1810
- * Props can either be provided as objects or as functions that take the previous props as an argument.
1811
- * The function will receive the merged props up to that point (going from left to right):
1812
- * so in the case of `(obj1, obj2, fn, obj3)`, `fn` will receive the merged props of `obj1` and `obj2`.
1813
- * The function is responsible for chaining event handlers if needed (that is, we don't run the merge logic).
1814
- *
1815
- * Event handlers returned by the functions are not automatically prevented when `preventBaseUIHandler` is called.
1816
- * They must check `event.baseUIHandlerPrevented` themselves and bail out if it's true.
1817
- *
1818
- * @important **`ref` is not merged.**
1819
- * @param a Props object to merge.
1820
- * @param b Props object to merge. The function will overwrite conflicting props from `a`.
1821
- * @param c Props object to merge. The function will overwrite conflicting props from previous parameters.
1822
- * @param d Props object to merge. The function will overwrite conflicting props from previous parameters.
1823
- * @param e Props object to merge. The function will overwrite conflicting props from previous parameters.
1824
- * @returns The merged props.
1825
- * @public
1826
- */
1827
- function mergeProps(a, b, c, d, e) {
1828
- if (!c && !d && !e && !a) return createInitialMergedProps(b);
1829
- let merged = createInitialMergedProps(a);
1830
- if (b) merged = mergeInto(merged, b);
1831
- if (c) merged = mergeInto(merged, c);
1832
- if (d) merged = mergeInto(merged, d);
1833
- if (e) merged = mergeInto(merged, e);
1834
- return merged;
1835
- }
1836
- /**
1837
- * Merges an arbitrary number of React props using the same logic as {@link mergeProps}.
1838
- * This function accepts an array of props instead of individual arguments.
1839
- *
1840
- * This has slightly lower performance than {@link mergeProps} due to accepting an array
1841
- * instead of a fixed number of arguments. Prefer {@link mergeProps} when merging 5 or
1842
- * fewer prop sets for better performance.
1843
- *
1844
- * @param props Array of props to merge.
1845
- * @returns The merged props.
1846
- * @see mergeProps
1847
- * @public
1848
- */
1849
- function mergePropsN(props) {
1850
- if (props.length === 0) return EMPTY_PROPS;
1851
- if (props.length === 1) return createInitialMergedProps(props[0]);
1852
- let merged = createInitialMergedProps(props[0]);
1853
- for (let i = 1; i < props.length; i += 1) merged = mergeInto(merged, props[i]);
1854
- return merged;
1855
- }
1856
- function createInitialMergedProps(inputProps) {
1857
- if (isPropsGetter(inputProps)) return { ...resolvePropsGetter(inputProps, EMPTY_PROPS) };
1858
- return copyInitialProps(inputProps);
1859
- }
1860
- function mergeInto(merged, inputProps) {
1861
- if (isPropsGetter(inputProps)) return resolvePropsGetter(inputProps, merged);
1862
- return mutablyMergeInto(merged, inputProps);
1863
- }
1864
- function copyInitialProps(inputProps) {
1865
- const copiedProps = { ...inputProps };
1866
- for (const propName in copiedProps) {
1867
- const propValue = copiedProps[propName];
1868
- if (isEventHandler(propName, propValue)) copiedProps[propName] = wrapEventHandler(propValue);
1869
- }
1870
- return copiedProps;
1871
- }
1872
- /**
1873
- * Merges two sets of props. In case of conflicts, the external props take precedence.
1874
- */
1875
- function mutablyMergeInto(mergedProps, externalProps) {
1876
- if (!externalProps) return mergedProps;
1877
- for (const propName in externalProps) {
1878
- const externalPropValue = externalProps[propName];
1879
- switch (propName) {
1880
- case "style":
1881
- mergedProps[propName] = mergeObjects(mergedProps.style, externalPropValue);
1882
- break;
1883
- case "className":
1884
- mergedProps[propName] = mergeClassNames(mergedProps.className, externalPropValue);
1885
- break;
1886
- default: if (isEventHandler(propName, externalPropValue)) mergedProps[propName] = mergeEventHandlers(mergedProps[propName], externalPropValue);
1887
- else mergedProps[propName] = externalPropValue;
1888
- }
1889
- }
1890
- return mergedProps;
1891
- }
1892
- function isEventHandler(key, value) {
1893
- const code0 = key.charCodeAt(0);
1894
- const code1 = key.charCodeAt(1);
1895
- const code2 = key.charCodeAt(2);
1896
- return code0 === 111 && code1 === 110 && code2 >= 65 && code2 <= 90 && (typeof value === "function" || typeof value === "undefined");
1897
- }
1898
- function isPropsGetter(inputProps) {
1899
- return typeof inputProps === "function";
1900
- }
1901
- function resolvePropsGetter(inputProps, previousProps) {
1902
- if (isPropsGetter(inputProps)) return inputProps(previousProps);
1903
- return inputProps ?? EMPTY_PROPS;
1904
- }
1905
- function mergeEventHandlers(ourHandler, theirHandler) {
1906
- if (!theirHandler) return ourHandler;
1907
- if (!ourHandler) return wrapEventHandler(theirHandler);
1908
- return (...args) => {
1909
- const event = args[0];
1910
- if (isSyntheticEvent(event)) {
1911
- const baseUIEvent = event;
1912
- makeEventPreventable(baseUIEvent);
1913
- const result = theirHandler(...args);
1914
- if (!baseUIEvent.baseUIHandlerPrevented) ourHandler?.(...args);
1915
- return result;
1916
- }
1917
- const result = theirHandler(...args);
1918
- ourHandler?.(...args);
1919
- return result;
1920
- };
1921
- }
1922
- function wrapEventHandler(handler) {
1923
- if (!handler) return handler;
1924
- return (...args) => {
1925
- const event = args[0];
1926
- if (isSyntheticEvent(event)) makeEventPreventable(event);
1927
- return handler(...args);
1928
- };
1929
- }
1930
- function makeEventPreventable(event) {
1931
- event.preventBaseUIHandler = () => {
1932
- event.baseUIHandlerPrevented = true;
1933
- };
1934
- return event;
1935
- }
1936
- function mergeClassNames(ourClassName, theirClassName) {
1937
- if (theirClassName) {
1938
- if (ourClassName) return theirClassName + " " + ourClassName;
1939
- return theirClassName;
1940
- }
1941
- return ourClassName;
1942
- }
1943
- function isSyntheticEvent(event) {
1944
- return event != null && typeof event === "object" && "nativeEvent" in event;
1945
- }
1946
- //#endregion
1947
- //#region ../../../node_modules/.pnpm/@base-ui+react@1.6.0_@types+react@18.3.28_date-fns@4.1.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@base-ui/react/internals/useRenderElement.mjs
1948
- /**
1949
- * Renders a Base UI element.
1950
- *
1951
- * @param element The default HTML element to render. Can be overridden by the `render` prop.
1952
- * @param componentProps An object containing the `render` and `className` props to be used for element customization. Other props are ignored.
1953
- * @param params Additional parameters for rendering the element.
1954
- */
1955
- function useRenderElement(element, componentProps, params = {}) {
1956
- const renderProp = componentProps.render;
1957
- const outProps = useRenderElementProps(componentProps, params);
1958
- if (params.enabled === false) return null;
1959
- return evaluateRenderProp(element, renderProp, outProps, params.state ?? EMPTY_OBJECT);
1960
- }
1961
- /**
1962
- * Computes render element final props.
1963
- */
1964
- function useRenderElementProps(componentProps, params = {}) {
1965
- const { className: classNameProp, style: styleProp, render: renderProp } = componentProps;
1966
- const { state = EMPTY_OBJECT, ref, props, stateAttributesMapping, enabled = true } = params;
1967
- const className = enabled ? resolveClassName(classNameProp, state) : void 0;
1968
- const style = enabled ? resolveStyle(styleProp, state) : void 0;
1969
- const stateProps = enabled ? getStateAttributesProps(state, stateAttributesMapping) : EMPTY_OBJECT;
1970
- const resolvedProps = enabled && props ? resolveRenderFunctionProps(props) : void 0;
1971
- const outProps = enabled ? mergeObjects(stateProps, resolvedProps) ?? {} : EMPTY_OBJECT;
1972
- if (typeof document !== "undefined") if (!enabled) useMergedRefs(null, null);
1973
- else if (Array.isArray(ref)) outProps.ref = useMergedRefsN([
1974
- outProps.ref,
1975
- getReactElementRef(renderProp),
1976
- ...ref
1977
- ]);
1978
- else outProps.ref = useMergedRefs(outProps.ref, getReactElementRef(renderProp), ref);
1979
- if (!enabled) return EMPTY_OBJECT;
1980
- if (className !== void 0) outProps.className = mergeClassNames(outProps.className, className);
1981
- if (style !== void 0) outProps.style = mergeObjects(outProps.style, style);
1982
- return outProps;
1983
- }
1984
- function resolveRenderFunctionProps(props) {
1985
- if (Array.isArray(props)) return mergePropsN(props);
1986
- return mergeProps(void 0, props);
1987
- }
1988
- const REACT_LAZY_TYPE = Symbol.for("react.lazy");
1989
- const COMPONENT_IDENTIFIER_PATTERN = /^[A-Z][A-Za-z0-9$]*$/;
1990
- const LOWERCASE_CHARACTER_PATTERN = /[a-z]/;
1991
- function evaluateRenderProp(element, render, props, state) {
1992
- if (render) {
1993
- if (typeof render === "function") {
1994
- if (process.env.NODE_ENV !== "production") warnIfRenderPropLooksLikeComponent(render);
1995
- return render(props, state);
1996
- }
1997
- const mergedProps = mergeProps(props, render.props);
1998
- mergedProps.ref = props.ref;
1999
- let newElement = render;
2000
- if (newElement?.$$typeof === REACT_LAZY_TYPE) newElement = React.Children.toArray(render)[0];
2001
- if (process.env.NODE_ENV !== "production") {
2002
- if (!/*#__PURE__*/ React.isValidElement(newElement)) throw new Error([
2003
- "Base UI: The `render` prop was provided an invalid React element as `React.isValidElement(render)` is `false`.",
2004
- "A valid React element must be provided to the `render` prop because it is cloned with props to replace the default element.",
2005
- "https://base-ui.com/r/invalid-render-prop"
2006
- ].join("\n"));
2007
- }
2008
- return /*#__PURE__*/ React.cloneElement(newElement, mergedProps);
2009
- }
2010
- if (element) {
2011
- if (typeof element === "string") return renderTag(element, props);
2012
- }
2013
- throw new Error(process.env.NODE_ENV !== "production" ? "Base UI: Render element or function are not defined." : formatErrorMessage(8));
2014
- }
2015
- function warnIfRenderPropLooksLikeComponent(renderFn) {
2016
- const functionName = renderFn.name;
2017
- if (functionName.length === 0) return;
2018
- if (!COMPONENT_IDENTIFIER_PATTERN.test(functionName)) return;
2019
- if (!LOWERCASE_CHARACTER_PATTERN.test(functionName)) return;
2020
- warn(`The \`render\` prop received a function named \`${functionName}\` that starts with an uppercase letter.`, "This usually means a React component was passed directly as `render={Component}`.", "Base UI calls `render` as a plain function, which can break the Rules of Hooks during reconciliation.", "If this is an intentional render callback, rename it to start with a lowercase letter.", "Use `render={<Component />}` or `render={(props) => <Component {...props} />}` instead.", "https://base-ui.com/r/invalid-render-prop");
2021
- }
2022
- function renderTag(Tag, props) {
2023
- if (Tag === "button") return /*#__PURE__*/ createElement("button", {
2024
- type: "button",
2025
- ...props,
2026
- key: props.key
2027
- });
2028
- if (Tag === "img") return /*#__PURE__*/ createElement("img", {
2029
- alt: "",
2030
- ...props,
2031
- key: props.key
2032
- });
2033
- return /*#__PURE__*/ React.createElement(Tag, props);
2034
- }
2035
- //#endregion
2036
- //#region ../../../node_modules/.pnpm/@floating-ui+utils@0.2.12/node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.mjs
2037
- function hasWindow() {
2038
- return typeof window !== "undefined";
2039
- }
2040
- function getWindow(node) {
2041
- var _node$ownerDocument;
2042
- return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
2043
- }
2044
- function isHTMLElement(value) {
2045
- if (!hasWindow()) return false;
2046
- return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;
2047
- }
2048
- //#endregion
2049
- //#region ../../../node_modules/.pnpm/@base-ui+react@1.6.0_@types+react@18.3.28_date-fns@4.1.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@base-ui/react/internals/composite/root/CompositeRootContext.mjs
2050
- const CompositeRootContext = /*#__PURE__*/ React.createContext(void 0);
2051
- if (process.env.NODE_ENV !== "production") CompositeRootContext.displayName = "CompositeRootContext";
2052
- function useCompositeRootContext(optional = false) {
2053
- const context = React.useContext(CompositeRootContext);
2054
- if (context === void 0 && !optional) throw new Error(process.env.NODE_ENV !== "production" ? "Base UI: CompositeRootContext is missing. Composite parts must be placed within <Composite.Root>." : formatErrorMessage(16));
2055
- return context;
2056
- }
2057
- //#endregion
2058
- //#region ../../../node_modules/.pnpm/@base-ui+react@1.6.0_@types+react@18.3.28_date-fns@4.1.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@base-ui/react/utils/useFocusableWhenDisabled.mjs
2059
- function useFocusableWhenDisabled(parameters) {
2060
- const { focusableWhenDisabled, disabled, composite = false, tabIndex: tabIndexProp = 0, isNativeButton } = parameters;
2061
- const isFocusableComposite = composite && focusableWhenDisabled !== false;
2062
- const isNonFocusableComposite = composite && focusableWhenDisabled === false;
2063
- return { props: React.useMemo(() => {
2064
- const additionalProps = { onKeyDown(event) {
2065
- if (disabled && focusableWhenDisabled && event.key !== "Tab") event.preventDefault();
2066
- } };
2067
- if (!composite) {
2068
- additionalProps.tabIndex = tabIndexProp;
2069
- if (!isNativeButton && disabled) additionalProps.tabIndex = focusableWhenDisabled ? tabIndexProp : -1;
2070
- }
2071
- if (isNativeButton && (focusableWhenDisabled || isFocusableComposite) || !isNativeButton && disabled) additionalProps["aria-disabled"] = disabled;
2072
- if (isNativeButton && (!focusableWhenDisabled || isNonFocusableComposite)) additionalProps.disabled = disabled;
2073
- return additionalProps;
2074
- }, [
2075
- composite,
2076
- disabled,
2077
- focusableWhenDisabled,
2078
- isFocusableComposite,
2079
- isNonFocusableComposite,
2080
- isNativeButton,
2081
- tabIndexProp
2082
- ]) };
2083
- }
2084
- //#endregion
2085
- //#region ../../../node_modules/.pnpm/@base-ui+react@1.6.0_@types+react@18.3.28_date-fns@4.1.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@base-ui/react/internals/use-button/useButton.mjs
2086
- function useButton(parameters = {}) {
2087
- const { disabled = false, focusableWhenDisabled, tabIndex = 0, native: isNativeButton = true, composite: compositeProp } = parameters;
2088
- const elementRef = React.useRef(null);
2089
- const compositeRootContext = useCompositeRootContext(true);
2090
- const isCompositeItem = compositeProp ?? compositeRootContext !== void 0;
2091
- const { props: focusableWhenDisabledProps } = useFocusableWhenDisabled({
2092
- focusableWhenDisabled,
2093
- disabled,
2094
- composite: isCompositeItem,
2095
- tabIndex,
2096
- isNativeButton
2097
- });
2098
- if (process.env.NODE_ENV !== "production") React.useEffect(() => {
2099
- if (!elementRef.current) return;
2100
- const isButtonTag = isButtonElement(elementRef.current);
2101
- if (isNativeButton) {
2102
- if (!isButtonTag) error(`A component that acts as a button expected a native <button> because the \`nativeButton\` prop is true. Rendering a non-<button> removes native button semantics, which can impact forms and accessibility. Use a real <button> in the \`render\` prop, or set \`nativeButton\` to \`false\`.${SafeReact.captureOwnerStack?.() || ""}`);
2103
- } else if (isButtonTag) error(`A component that acts as a button expected a non-<button> because the \`nativeButton\` prop is false. Rendering a <button> keeps native behavior while Base UI applies non-native attributes and handlers, which can add unintended extra attributes (such as \`role\` or \`aria-disabled\`). Use a non-<button> in the \`render\` prop, or set \`nativeButton\` to \`true\`.${SafeReact.captureOwnerStack?.() || ""}`);
2104
- }, [isNativeButton]);
2105
- const updateDisabled = React.useCallback(() => {
2106
- const element = elementRef.current;
2107
- if (!isButtonElement(element)) return;
2108
- if (isCompositeItem && disabled && focusableWhenDisabledProps.disabled === void 0 && element.disabled) element.disabled = false;
2109
- }, [
2110
- disabled,
2111
- focusableWhenDisabledProps.disabled,
2112
- isCompositeItem
2113
- ]);
2114
- useIsoLayoutEffect(updateDisabled, [updateDisabled]);
2115
- return {
2116
- getButtonProps: React.useCallback((externalProps = {}) => {
2117
- const { onClick: externalOnClick, onMouseDown: externalOnMouseDown, onKeyUp: externalOnKeyUp, onKeyDown: externalOnKeyDown, onPointerDown: externalOnPointerDown, ...otherExternalProps } = externalProps;
2118
- return mergeProps({
2119
- onClick(event) {
2120
- if (disabled) {
2121
- event.preventDefault();
2122
- return;
2123
- }
2124
- externalOnClick?.(event);
2125
- },
2126
- onMouseDown(event) {
2127
- if (!disabled) externalOnMouseDown?.(event);
2128
- },
2129
- onKeyDown(event) {
2130
- if (disabled) return;
2131
- makeEventPreventable(event);
2132
- externalOnKeyDown?.(event);
2133
- if (event.baseUIHandlerPrevented) return;
2134
- const isCurrentTarget = event.target === event.currentTarget;
2135
- const currentTarget = event.currentTarget;
2136
- const isButton = isButtonElement(currentTarget);
2137
- const isLink = !isNativeButton && isValidLinkElement(currentTarget);
2138
- const shouldClick = isCurrentTarget && (isNativeButton ? isButton : !isLink);
2139
- const isEnterKey = event.key === "Enter";
2140
- const isSpaceKey = event.key === " ";
2141
- const role = currentTarget.getAttribute("role");
2142
- const isTextNavigationRole = role?.startsWith("menuitem") || role === "option" || role === "gridcell";
2143
- if (isCurrentTarget && isCompositeItem && isSpaceKey) {
2144
- if (event.defaultPrevented && isTextNavigationRole) return;
2145
- event.preventDefault();
2146
- if (isLink || isNativeButton && isButton) {
2147
- currentTarget.click();
2148
- event.preventBaseUIHandler();
2149
- } else if (shouldClick) {
2150
- externalOnClick?.(event);
2151
- event.preventBaseUIHandler();
2152
- }
2153
- return;
2154
- }
2155
- if (shouldClick) {
2156
- if (!isNativeButton && (isSpaceKey || isEnterKey)) event.preventDefault();
2157
- if (!isNativeButton && isEnterKey) externalOnClick?.(event);
2158
- }
2159
- },
2160
- onKeyUp(event) {
2161
- if (disabled) return;
2162
- makeEventPreventable(event);
2163
- externalOnKeyUp?.(event);
2164
- if (event.target === event.currentTarget && isNativeButton && isCompositeItem && isButtonElement(event.currentTarget) && event.key === " ") {
2165
- event.preventDefault();
2166
- return;
2167
- }
2168
- if (event.baseUIHandlerPrevented) return;
2169
- if (event.target === event.currentTarget && !isNativeButton && !isCompositeItem && event.key === " ") externalOnClick?.(event);
2170
- },
2171
- onPointerDown(event) {
2172
- if (disabled) {
2173
- event.preventDefault();
2174
- return;
2175
- }
2176
- externalOnPointerDown?.(event);
2177
- }
2178
- }, isNativeButton ? { type: "button" } : { role: "button" }, focusableWhenDisabledProps, otherExternalProps);
2179
- }, [
2180
- disabled,
2181
- focusableWhenDisabledProps,
2182
- isCompositeItem,
2183
- isNativeButton
2184
- ]),
2185
- buttonRef: useStableCallback((element) => {
2186
- elementRef.current = element;
2187
- updateDisabled();
2188
- })
2189
- };
2190
- }
2191
- function isButtonElement(elem) {
2192
- return isHTMLElement(elem) && elem.tagName === "BUTTON";
2193
- }
2194
- function isValidLinkElement(elem) {
2195
- return Boolean(elem?.tagName === "A" && elem?.href);
2196
- }
2197
- //#endregion
2198
- //#region ../../../node_modules/.pnpm/@base-ui+react@1.6.0_@types+react@18.3.28_date-fns@4.1.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@base-ui/react/button/Button.mjs
2199
- /**
2200
- * A button component that can be used to trigger actions.
2201
- * Renders a `<button>` element.
2202
- *
2203
- * Documentation: [Base UI Button](https://base-ui.com/react/components/button)
2204
- */
2205
- const Button$2 = /*#__PURE__*/ React.forwardRef(function Button(componentProps, forwardedRef) {
2206
- const { render, className, disabled = false, focusableWhenDisabled = false, nativeButton = true, style, ...elementProps } = componentProps;
2207
- const { getButtonProps, buttonRef } = useButton({
2208
- disabled,
2209
- focusableWhenDisabled,
2210
- native: nativeButton
2211
- });
2212
- return useRenderElement("button", componentProps, {
2213
- state: { disabled },
2214
- ref: [forwardedRef, buttonRef],
2215
- props: [elementProps, getButtonProps]
2216
- });
2217
- });
2218
- if (process.env.NODE_ENV !== "production") Button$2.displayName = "Button";
2219
- //#endregion
2220
- //#region ../../../node_modules/.pnpm/@base-ui+react@1.6.0_@types+react@18.3.28_date-fns@4.1.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@base-ui/react/use-render/useRender.mjs
2221
- /**
2222
- * Renders a Base UI element.
2223
- *
2224
- * @public
2225
- */
2226
- function useRender(params) {
2227
- return useRenderElement(params.defaultTagName ?? "div", params, params);
2228
- }
2229
- //#endregion
2230
- //#region ../../../node_modules/.pnpm/@wordpress+ui@0.17.0_@types+react@18.3.28_date-fns@4.1.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/ui/build-module/text/text.mjs
2231
- var STYLE_HASH_ATTRIBUTE$3 = "data-wp-hash";
2232
- function getRuntime$3() {
2233
- const globalScope = globalThis;
2234
- if (globalScope.__wpStyleRuntime) return globalScope.__wpStyleRuntime;
2235
- globalScope.__wpStyleRuntime = {
2236
- documents: /* @__PURE__ */ new Map(),
2237
- styles: /* @__PURE__ */ new Map(),
2238
- injectedStyles: /* @__PURE__ */ new WeakMap()
2239
- };
2240
- if (typeof document !== "undefined") registerDocument$3(document);
2241
- return globalScope.__wpStyleRuntime;
2242
- }
2243
- function documentContainsStyleHash$3(targetDocument, hash) {
2244
- if (!targetDocument.head) return false;
2245
- for (const style of targetDocument.head.querySelectorAll(`style[${STYLE_HASH_ATTRIBUTE$3}]`)) if (style.getAttribute(STYLE_HASH_ATTRIBUTE$3) === hash) return true;
2246
- return false;
2247
- }
2248
- function injectStyle$3(targetDocument, hash, css) {
2249
- if (!targetDocument.head) return;
2250
- const runtime = getRuntime$3();
2251
- let injectedStyles = runtime.injectedStyles.get(targetDocument);
2252
- if (!injectedStyles) {
2253
- injectedStyles = /* @__PURE__ */ new Set();
2254
- runtime.injectedStyles.set(targetDocument, injectedStyles);
2255
- }
2256
- if (injectedStyles.has(hash)) return;
2257
- if (documentContainsStyleHash$3(targetDocument, hash)) {
2258
- injectedStyles.add(hash);
2259
- return;
2260
- }
2261
- const style = targetDocument.createElement("style");
2262
- style.setAttribute(STYLE_HASH_ATTRIBUTE$3, hash);
2263
- style.appendChild(targetDocument.createTextNode(css));
2264
- targetDocument.head.appendChild(style);
2265
- injectedStyles.add(hash);
2266
- }
2267
- function registerDocument$3(targetDocument) {
2268
- const runtime = getRuntime$3();
2269
- runtime.documents.set(targetDocument, (runtime.documents.get(targetDocument) ?? 0) + 1);
2270
- for (const [hash, css] of runtime.styles) injectStyle$3(targetDocument, hash, css);
2271
- return () => {
2272
- const count = runtime.documents.get(targetDocument);
2273
- if (count === void 0) return;
2274
- if (count <= 1) {
2275
- runtime.documents.delete(targetDocument);
2276
- return;
2277
- }
2278
- runtime.documents.set(targetDocument, count - 1);
2279
- };
2280
- }
2281
- function registerStyle$3(hash, css) {
2282
- const runtime = getRuntime$3();
2283
- runtime.styles.set(hash, css);
2284
- for (const targetDocument of runtime.documents.keys()) injectStyle$3(targetDocument, hash, css);
2285
- }
2286
- if (typeof process === "undefined" || process.env.NODE_ENV !== "test") registerStyle$3("0c5702ddca", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._83ed8a8da5dd50ea__text{margin:0}._14437cfb77831647__heading-2xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-2xl,32px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-medium,499);--_gcd-p-font-size:var(--wpds-typography-font-size-2xl,32px);--_gcd-p-line-height:var(--wpds-typography-line-height-2xl,40px);font-size:var(--wpds-typography-font-size-2xl,32px);line-height:var(--wpds-typography-line-height-2xl,40px)}._14437cfb77831647__heading-2xl,._3c78b7fa9b4072dd__heading-xl{font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,\"Segoe UI\",\"Roboto\",\"Oxygen-Sans\",\"Ubuntu\",\"Cantarell\",\"Helvetica Neue\",sans-serif);font-weight:var(--wpds-typography-font-weight-medium,499)}._3c78b7fa9b4072dd__heading-xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-medium,499);--_gcd-p-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-p-line-height:var(--wpds-typography-line-height-md,24px);font-size:var(--wpds-typography-font-size-xl,20px);line-height:var(--wpds-typography-line-height-md,24px)}.aa58f227716bcde2__heading-lg{--_gcd-heading-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-medium,499);--_gcd-p-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-lg,15px)}.aa58f227716bcde2__heading-lg,.fc4da56d8dfe52c4__heading-md{font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,\"Segoe UI\",\"Roboto\",\"Oxygen-Sans\",\"Ubuntu\",\"Cantarell\",\"Helvetica Neue\",sans-serif);font-weight:var(--wpds-typography-font-weight-medium,499);line-height:var(--wpds-typography-line-height-sm,20px)}.fc4da56d8dfe52c4__heading-md{--_gcd-heading-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-medium,499);--_gcd-p-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-md,13px)}.a9b78c7c82e8dff7__heading-sm{--_gcd-heading-font-size:var(--wpds-typography-font-size-xs,11px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-medium,499);--_gcd-p-font-size:var(--wpds-typography-font-size-xs,11px);--_gcd-p-line-height:var(--wpds-typography-line-height-xs,16px);font-family:var(--wpds-typography-font-family-heading,-apple-system,system-ui,\"Segoe UI\",\"Roboto\",\"Oxygen-Sans\",\"Ubuntu\",\"Cantarell\",\"Helvetica Neue\",sans-serif);font-size:var(--wpds-typography-font-size-xs,11px);font-weight:var(--wpds-typography-font-weight-medium,499);line-height:var(--wpds-typography-line-height-xs,16px);text-transform:uppercase}._305ff559e52180d5__body-xl{--_gcd-heading-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-regular,400);--_gcd-p-font-size:var(--wpds-typography-font-size-xl,20px);--_gcd-p-line-height:var(--wpds-typography-line-height-xl,32px);font-size:var(--wpds-typography-font-size-xl,20px);line-height:var(--wpds-typography-line-height-xl,32px)}._305ff559e52180d5__body-xl,.ca1aa3fc2029e958__body-lg{font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,\"Segoe UI\",\"Roboto\",\"Oxygen-Sans\",\"Ubuntu\",\"Cantarell\",\"Helvetica Neue\",sans-serif);font-weight:var(--wpds-typography-font-weight-regular,400)}.ca1aa3fc2029e958__body-lg{--_gcd-heading-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-regular,400);--_gcd-p-font-size:var(--wpds-typography-font-size-lg,15px);--_gcd-p-line-height:var(--wpds-typography-line-height-md,24px);font-size:var(--wpds-typography-font-size-lg,15px);line-height:var(--wpds-typography-line-height-md,24px)}._131101940be12424__body-md{--_gcd-heading-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-regular,400);--_gcd-p-font-size:var(--wpds-typography-font-size-md,13px);--_gcd-p-line-height:var(--wpds-typography-line-height-sm,20px);font-size:var(--wpds-typography-font-size-md,13px);line-height:var(--wpds-typography-line-height-sm,20px)}._0e8d87a42c1f75fa__body-sm,._131101940be12424__body-md{font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,\"Segoe UI\",\"Roboto\",\"Oxygen-Sans\",\"Ubuntu\",\"Cantarell\",\"Helvetica Neue\",sans-serif);font-weight:var(--wpds-typography-font-weight-regular,400)}._0e8d87a42c1f75fa__body-sm{--_gcd-heading-font-size:var(--wpds-typography-font-size-sm,12px);--_gcd-heading-font-weight:var(--wpds-typography-font-weight-regular,400);--_gcd-p-font-size:var(--wpds-typography-font-size-sm,12px);--_gcd-p-line-height:var(--wpds-typography-line-height-xs,16px);font-size:var(--wpds-typography-font-size-sm,12px);line-height:var(--wpds-typography-line-height-xs,16px)}}}");
2287
- var style_default$3 = {
2288
- "text": "_83ed8a8da5dd50ea__text",
2289
- "heading-2xl": "_14437cfb77831647__heading-2xl",
2290
- "heading-xl": "_3c78b7fa9b4072dd__heading-xl",
2291
- "heading-lg": "aa58f227716bcde2__heading-lg",
2292
- "heading-md": "fc4da56d8dfe52c4__heading-md",
2293
- "heading-sm": "a9b78c7c82e8dff7__heading-sm",
2294
- "body-xl": "_305ff559e52180d5__body-xl",
2295
- "body-lg": "ca1aa3fc2029e958__body-lg",
2296
- "body-md": "_131101940be12424__body-md",
2297
- "body-sm": "_0e8d87a42c1f75fa__body-sm"
2298
- };
2299
- if (typeof process === "undefined" || process.env.NODE_ENV !== "test") registerStyle$3("d390e935a7", "._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-medium,499));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}");
2300
- var global_css_defense_default$1 = {
2301
- "button": "_6defc79820e382c6__button",
2302
- "input": "d2cff2e5dea83bd1__input",
2303
- "textarea": "_547d86373d02e108__textarea",
2304
- "div": "_8c15fd0ed9f28ba4__div",
2305
- "p": "_43cec3e1eec1066d__p",
2306
- "heading": "e97669c6d9a38497__heading",
2307
- "a": "_2c0831b0499dbd6e__a"
2308
- };
2309
- var Text$1 = forwardRef$1(function Text2({ variant = "body-md", render, className, ...props }, ref) {
2310
- return useRender({
2311
- render,
2312
- defaultTagName: "span",
2313
- ref,
2314
- props: mergeProps(props, { className: clsx(style_default$3.text, global_css_defense_default$1.heading, global_css_defense_default$1.p, style_default$3[variant], className) })
2315
- });
2316
- });
2317
- //#endregion
2318
- //#region ../../../node_modules/.pnpm/@wordpress+dom-ready@4.51.0/node_modules/@wordpress/dom-ready/build-module/index.mjs
2319
- function domReady(callback) {
2320
- if (typeof document === "undefined") return;
2321
- if (document.readyState === "complete" || document.readyState === "interactive") {
2322
- callback();
2323
- return;
2324
- }
2325
- document.addEventListener("DOMContentLoaded", callback);
2326
- }
2327
- //#endregion
2328
- //#region ../../../node_modules/.pnpm/@wordpress+a11y@4.51.0/node_modules/@wordpress/a11y/build-module/script/add-container.mjs
2329
- function addContainer(ariaLive = "polite") {
2330
- const container = document.createElement("div");
2331
- container.id = `a11y-speak-${ariaLive}`;
2332
- container.className = "a11y-speak-region";
2333
- container.setAttribute("style", "position:absolute;margin:-1px;padding:0;height:1px;width:1px;overflow:hidden;clip-path:inset(50%);border:0;word-wrap:normal !important;word-break:normal !important;");
2334
- container.setAttribute("aria-live", ariaLive);
2335
- container.setAttribute("aria-relevant", "additions text");
2336
- container.setAttribute("aria-atomic", "true");
2337
- const { body } = document;
2338
- if (body) body.appendChild(container);
2339
- return container;
2340
- }
2341
- //#endregion
2342
- //#region ../../../node_modules/.pnpm/@wordpress+a11y@4.51.0/node_modules/@wordpress/a11y/build-module/script/add-intro-text.mjs
2343
- function addIntroText() {
2344
- const introText = document.createElement("p");
2345
- introText.id = "a11y-speak-intro-text";
2346
- introText.className = "a11y-speak-intro-text";
2347
- introText.textContent = __("Notifications");
2348
- introText.setAttribute("style", "position:absolute;margin:-1px;padding:0;height:1px;width:1px;overflow:hidden;clip-path:inset(50%);border:0;word-wrap:normal !important;word-break:normal !important;");
2349
- introText.setAttribute("hidden", "");
2350
- const { body } = document;
2351
- if (body) body.appendChild(introText);
2352
- return introText;
2353
- }
2354
- //#endregion
2355
- //#region ../../../node_modules/.pnpm/@wordpress+a11y@4.51.0/node_modules/@wordpress/a11y/build-module/shared/clear.mjs
2356
- function clear() {
2357
- const regions = document.getElementsByClassName("a11y-speak-region");
2358
- const introText = document.getElementById("a11y-speak-intro-text");
2359
- for (let i = 0; i < regions.length; i++) regions[i].textContent = "";
2360
- if (introText) introText.setAttribute("hidden", "hidden");
2361
- }
2362
- //#endregion
2363
- //#region ../../../node_modules/.pnpm/@wordpress+a11y@4.51.0/node_modules/@wordpress/a11y/build-module/shared/filter-message.mjs
2364
- var previousMessage = "";
2365
- function filterMessage(message) {
2366
- message = message.replace(/<[^<>]+>/g, " ");
2367
- if (previousMessage === message) message += "\xA0";
2368
- previousMessage = message;
2369
- return message;
2370
- }
2371
- //#endregion
2372
- //#region ../../../node_modules/.pnpm/@wordpress+a11y@4.51.0/node_modules/@wordpress/a11y/build-module/shared/index.mjs
2373
- function speak(message, ariaLive) {
2374
- clear();
2375
- message = filterMessage(message);
2376
- const introText = document.getElementById("a11y-speak-intro-text");
2377
- const containerAssertive = document.getElementById("a11y-speak-assertive");
2378
- const containerPolite = document.getElementById("a11y-speak-polite");
2379
- if (containerAssertive && ariaLive === "assertive") containerAssertive.textContent = message;
2380
- else if (containerPolite) containerPolite.textContent = message;
2381
- if (introText) introText.removeAttribute("hidden");
2382
- }
2383
- //#endregion
2384
- //#region ../../../node_modules/.pnpm/@wordpress+a11y@4.51.0/node_modules/@wordpress/a11y/build-module/index.mjs
2385
- function setup() {
2386
- const introText = document.getElementById("a11y-speak-intro-text");
2387
- const containerAssertive = document.getElementById("a11y-speak-assertive");
2388
- const containerPolite = document.getElementById("a11y-speak-polite");
2389
- if (introText === null) addIntroText();
2390
- if (containerAssertive === null) addContainer("assertive");
2391
- if (containerPolite === null) addContainer("polite");
2392
- }
2393
- domReady(setup);
2394
- //#endregion
2395
- //#region ../../../node_modules/.pnpm/@wordpress+ui@0.17.0_@types+react@18.3.28_date-fns@4.1.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/ui/build-module/button/button.mjs
2396
- var STYLE_HASH_ATTRIBUTE$2 = "data-wp-hash";
2397
- function getRuntime$2() {
2398
- const globalScope = globalThis;
2399
- if (globalScope.__wpStyleRuntime) return globalScope.__wpStyleRuntime;
2400
- globalScope.__wpStyleRuntime = {
2401
- documents: /* @__PURE__ */ new Map(),
2402
- styles: /* @__PURE__ */ new Map(),
2403
- injectedStyles: /* @__PURE__ */ new WeakMap()
2404
- };
2405
- if (typeof document !== "undefined") registerDocument$2(document);
2406
- return globalScope.__wpStyleRuntime;
2407
- }
2408
- function documentContainsStyleHash$2(targetDocument, hash) {
2409
- if (!targetDocument.head) return false;
2410
- for (const style of targetDocument.head.querySelectorAll(`style[${STYLE_HASH_ATTRIBUTE$2}]`)) if (style.getAttribute(STYLE_HASH_ATTRIBUTE$2) === hash) return true;
2411
- return false;
2412
- }
2413
- function injectStyle$2(targetDocument, hash, css) {
2414
- if (!targetDocument.head) return;
2415
- const runtime = getRuntime$2();
2416
- let injectedStyles = runtime.injectedStyles.get(targetDocument);
2417
- if (!injectedStyles) {
2418
- injectedStyles = /* @__PURE__ */ new Set();
2419
- runtime.injectedStyles.set(targetDocument, injectedStyles);
2420
- }
2421
- if (injectedStyles.has(hash)) return;
2422
- if (documentContainsStyleHash$2(targetDocument, hash)) {
2423
- injectedStyles.add(hash);
2424
- return;
2425
- }
2426
- const style = targetDocument.createElement("style");
2427
- style.setAttribute(STYLE_HASH_ATTRIBUTE$2, hash);
2428
- style.appendChild(targetDocument.createTextNode(css));
2429
- targetDocument.head.appendChild(style);
2430
- injectedStyles.add(hash);
2431
- }
2432
- function registerDocument$2(targetDocument) {
2433
- const runtime = getRuntime$2();
2434
- runtime.documents.set(targetDocument, (runtime.documents.get(targetDocument) ?? 0) + 1);
2435
- for (const [hash, css] of runtime.styles) injectStyle$2(targetDocument, hash, css);
2436
- return () => {
2437
- const count = runtime.documents.get(targetDocument);
2438
- if (count === void 0) return;
2439
- if (count <= 1) {
2440
- runtime.documents.delete(targetDocument);
2441
- return;
2442
- }
2443
- runtime.documents.set(targetDocument, count - 1);
1410
+ allSegmentsHidden: useMemo(() => {
1411
+ return legendInteractive && visibleData.length === 0;
1412
+ }, [legendInteractive, visibleData]),
1413
+ legendData: useMemo(() => {
1414
+ if (!legendInteractive || !chartId) return data;
1415
+ const visibleDataMap = new Map(visibleData.map((d) => [d.label, d]));
1416
+ return data.map((segment) => {
1417
+ if (!isSeriesVisible(chartId, segment.label)) return segment;
1418
+ return visibleDataMap.get(segment.label) || segment;
1419
+ });
1420
+ }, [
1421
+ data,
1422
+ visibleData,
1423
+ legendInteractive,
1424
+ chartId,
1425
+ isSeriesVisible
1426
+ ])
2444
1427
  };
1428
+ };
1429
+ //#endregion
1430
+ //#region src/hooks/use-prefers-reduced-motion.ts
1431
+ const QUERY = "(prefers-reduced-motion: no-preference)";
1432
+ const getInitialState = () => !window.matchMedia(QUERY).matches;
1433
+ /**
1434
+ * Custom hook to determine if the user prefers reduced motion.
1435
+ * @return {boolean} A boolean indicating the user's preference for reduced motion.
1436
+ */
1437
+ function usePrefersReducedMotion() {
1438
+ const [prefersReducedMotion, setPrefersReducedMotion] = useState(getInitialState);
1439
+ useEffect(() => {
1440
+ const mediaQueryList = window.matchMedia(QUERY);
1441
+ const listener = (event) => {
1442
+ setPrefersReducedMotion(!event.matches);
1443
+ };
1444
+ mediaQueryList.addEventListener("change", listener);
1445
+ return () => {
1446
+ mediaQueryList.removeEventListener("change", listener);
1447
+ };
1448
+ }, []);
1449
+ return prefersReducedMotion;
2445
1450
  }
2446
- function registerStyle$2(hash, css) {
2447
- const runtime = getRuntime$2();
2448
- runtime.styles.set(hash, css);
2449
- for (const targetDocument of runtime.documents.keys()) injectStyle$2(targetDocument, hash, css);
2450
- }
2451
- if (typeof process === "undefined" || process.env.NODE_ENV !== "test") registerStyle$2("4c317b0736", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._97b0fc33c028be1a__button,.abbb272e2ce49bd6__is-unstyled{appearance:none;padding:0}._97b0fc33c028be1a__button{--wp-ui-button-font-weight:var(--wpds-typography-font-weight-medium,499);--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-strong,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-strong-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 93%,#000));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand-strong,#fff);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-strong-active,#fff);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-strong-disabled,#8d8d8d);--wp-ui-button-padding-block:var(--wpds-dimension-padding-xs,4px);--wp-ui-button-padding-inline:var(--wpds-dimension-padding-md,12px);--wp-ui-button-height:var(--wpds-dimension-size-lg,40px);--wp-ui-button-aspect-ratio:auto;--wp-ui-button-font-size:var(--wpds-typography-font-size-md,13px);--wp-ui-button-min-width:calc(4ch + var(--wp-ui-button-padding-inline)*2);--wp-ui-button-icon-margin:calc((var(--wpds-dimension-size-2xs, 16px) - var(--wpds-dimension-size-sm, 24px))/2);--wp-ui-button-border-color:var(--wp-ui-button-background-color);--wp-ui-button-border-color-active:var(--wp-ui-button-background-color-active);--wp-ui-button-border-color-disabled:var(--wp-ui-button-background-color-disabled);--_gcd-button-font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,\"Segoe UI\",\"Roboto\",\"Oxygen-Sans\",\"Ubuntu\",\"Cantarell\",\"Helvetica Neue\",sans-serif);--_gcd-button-font-size:var(--wp-ui-button-font-size);--_gcd-button-font-weight:var(--wp-ui-button-font-weight);align-items:center;aspect-ratio:var(--wp-ui-button-aspect-ratio);background-clip:padding-box;background-color:var(--wp-ui-button-background-color);border-color:var(--wp-ui-button-border-color);border-radius:var(--wpds-border-radius-sm,2px);border-style:solid;border-width:1px;color:var(--wp-ui-button-foreground-color);display:inline-flex;font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,\"Segoe UI\",\"Roboto\",\"Oxygen-Sans\",\"Ubuntu\",\"Cantarell\",\"Helvetica Neue\",sans-serif);font-size:var(--wp-ui-button-font-size);font-weight:var(--wp-ui-button-font-weight);gap:var(--wpds-dimension-gap-sm,8px);justify-content:center;line-height:var(--wpds-typography-line-height-sm,20px);max-width:100%;min-height:var(--wp-ui-button-height);min-width:var(--wp-ui-button-min-width);overflow-wrap:anywhere;padding-block:var(--wp-ui-button-padding-block);padding-inline:var(--wp-ui-button-padding-inline);position:relative;text-align:center;text-decoration:none;&:not([data-disabled]){cursor:var(--wpds-cursor-control,pointer)}@media not (prefers-reduced-motion){transition:color .1s ease-out;*{transition:opacity .1s ease-out}}&[href]{cursor:pointer}[href]{color:inherit;text-decoration:inherit}&:not([data-disabled]):is(:hover,:active,:focus){background-color:var(--wp-ui-button-background-color-active);border-color:var(--wp-ui-button-border-color-active);color:var(--wp-ui-button-foreground-color-active)}&[data-disabled]:not(._914b42f315c0e580__is-loading){background-color:var(--wp-ui-button-background-color-disabled);border-color:var(--wp-ui-button-border-color-disabled);color:var(--wp-ui-button-foreground-color-disabled);@media (forced-colors:active){border-bottom-color:GrayText;border-left-color:GrayText;border-right-color:GrayText;border-top-color:GrayText;color:GrayText}}&:before{aspect-ratio:1;border:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid;border-block-end-color:transparent;border-block-start-color:var(--wp-ui-button-foreground-color);border-inline-end-color:var(--wp-ui-button-foreground-color);border-inline-start-color:transparent;border-radius:50%;box-sizing:border-box;content:\"\";display:block;height:var(--wp-ui-button-font-size);inset-inline-start:50%;opacity:0;pointer-events:none;position:absolute;top:50%;transform:translate(-50%,-50%);@media not (prefers-reduced-motion){transition:opacity .1s ease-out}@media (forced-colors:active){border-block-end-style:none;border-bottom-color:ButtonText;border-inline-start-style:none;border-left-color:ButtonText;border-right-color:ButtonText;border-top-color:ButtonText}}}._908205475f9f2a92__is-small{--wp-ui-button-padding-block:0;--wp-ui-button-padding-inline:var(--wpds-dimension-padding-sm,8px);--wp-ui-button-height:var(--wpds-dimension-size-sm,24px)}._9f6fc6553aeb36fe__icon{margin:var(--wp-ui-button-icon-margin)}.dd460c965226cc77__is-brand{&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 85%,#000));--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-brand-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000)}}.e722a8f96726aa99__is-neutral{&.ad0619a3217c6a5b__is-minimal[aria-pressed=true],&.b50b3358c5fb4d0b__is-solid{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-strong,#2d2d2d);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-strong-active,#1e1e1e);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral-strong,#f0f0f0);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-strong-active,#f0f0f0);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-strong-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d);--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-neutral-active,#6e6e6e);--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-neutral-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000)}}.abbb272e2ce49bd6__is-unstyled{background:none;border:none;min-width:unset}.cf59cf1b69629838__is-compact{--wp-ui-button-height:var(--wpds-dimension-size-md,32px)}._914b42f315c0e580__is-loading:not(.abbb272e2ce49bd6__is-unstyled){color:transparent;&:not([data-disabled]):is(:hover,:active,:focus){color:transparent}@media (forced-colors:active){color:ButtonFace}*{opacity:0}&:before{opacity:1;transition-delay:.05s;@media not (prefers-reduced-motion){animation:_5a1d53da6f830c8d__loading-animation 1s linear infinite}}}}@keyframes _5a1d53da6f830c8d__loading-animation{0%{transform:translate(-50%,-50%) rotate(0deg)}to{transform:translate(-50%,-50%) rotate(1turn)}}}");
2452
- var style_default$2 = {
2453
- "button": "_97b0fc33c028be1a__button",
2454
- "is-unstyled": "abbb272e2ce49bd6__is-unstyled",
2455
- "is-loading": "_914b42f315c0e580__is-loading",
2456
- "is-small": "_908205475f9f2a92__is-small",
2457
- "icon": "_9f6fc6553aeb36fe__icon",
2458
- "is-brand": "dd460c965226cc77__is-brand",
2459
- "is-outline": "_62d5a778b7b258ee__is-outline",
2460
- "is-minimal": "ad0619a3217c6a5b__is-minimal",
2461
- "is-neutral": "e722a8f96726aa99__is-neutral",
2462
- "is-solid": "b50b3358c5fb4d0b__is-solid",
2463
- "is-compact": "cf59cf1b69629838__is-compact",
2464
- "loading-animation": "_5a1d53da6f830c8d__loading-animation"
2465
- };
2466
- if (typeof process === "undefined" || process.env.NODE_ENV !== "test") registerStyle$2("10f3806643", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._336cd3e4e743482f__box-sizing{box-sizing:border-box;*,:after,:before{box-sizing:inherit}}}}");
2467
- var resets_default = { "box-sizing": "_336cd3e4e743482f__box-sizing" };
2468
- if (typeof process === "undefined" || process.env.NODE_ENV !== "test") registerStyle$2("5f8e7aa0bc", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer utilities{._08e8a2e44959f892__outset-ring--focus:focus,._970d04df7376df67__outset-ring--focus-within-except-active:focus-within:not(:has(:active)),.c5cb3ee4bddaa8e4__outset-ring--focus-within-visible:focus-within:has(:focus-visible),.cd83dfc2126a0846__outset-ring--focus-within:focus-within,.d0541bc9dd9dc7b6__outset-ring--focus-visible:focus-visible,.e25b2bdd7aa21721__outset-ring--focus-except-active:focus:not(:active),:focus-visible .ecadb9e080e2dfa5__outset-ring--focus-parent-visible{--_gcd-a-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9));--_gcd-div-outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9));outline:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid var(--wpds-color-stroke-focus,var(--wp-admin-theme-color,#3858e9));outline-offset:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px))}}}");
2469
- var focus_default = {
2470
- "outset-ring--focus": "_08e8a2e44959f892__outset-ring--focus",
2471
- "outset-ring--focus-except-active": "e25b2bdd7aa21721__outset-ring--focus-except-active",
2472
- "outset-ring--focus-visible": "d0541bc9dd9dc7b6__outset-ring--focus-visible",
2473
- "outset-ring--focus-within": "cd83dfc2126a0846__outset-ring--focus-within",
2474
- "outset-ring--focus-within-except-active": "_970d04df7376df67__outset-ring--focus-within-except-active",
2475
- "outset-ring--focus-within-visible": "c5cb3ee4bddaa8e4__outset-ring--focus-within-visible",
2476
- "outset-ring--focus-parent-visible": "ecadb9e080e2dfa5__outset-ring--focus-parent-visible"
2477
- };
2478
- if (typeof process === "undefined" || process.env.NODE_ENV !== "test") registerStyle$2("d390e935a7", "._6defc79820e382c6__button{box-sizing:var(--_gcd-button-box-sizing,border-box);font-family:var(--_gcd-button-font-family,inherit);font-size:var(--_gcd-button-font-size,inherit);font-weight:var(--_gcd-button-font-weight,inherit)}.d2cff2e5dea83bd1__input{box-sizing:var(--_gcd-input-box-sizing,border-box);font-family:var(--_gcd-input-font-family,inherit);font-size:var(--_gcd-input-font-size,inherit);font-weight:var(--_gcd-input-font-weight,inherit);margin:var(--_gcd-input-margin,0);&:is(textarea,[type=text],[type=password],[type=color],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){background-color:var(--_gcd-input-background-color,transparent);border:var(--_gcd-input-border,none);border-radius:var(--_gcd-input-border-radius,0);box-shadow:var(--_gcd-input-box-shadow,0 0 0 transparent);color:var(--_gcd-input-color,var(--wpds-color-foreground-interactive-neutral,#1e1e1e));&:focus{border-color:var(--_gcd-input-border-color-focus,var(--wp-admin-theme-color));box-shadow:var(--_gcd-input-box-shadow-focus,none);outline:var(--_gcd-input-outline-focus,none)}&:disabled{background:var(--_gcd-input-background-disabled,transparent);border-color:var(--_gcd-input-border-color-disabled,transparent);box-shadow:var(--_gcd-input-box-shadow-disabled,none);color:var(--_gcd-input-color-disabled,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}&::placeholder{color:var(--_gcd-input-placeholder-color,var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d))}}&:is(textarea,[type=text],[type=password],[type=date],[type=datetime],[type=datetime-local],[type=email],[type=month],[type=number],[type=search],[type=tel],[type=time],[type=url],[type=week]){line-height:var(--_gcd-input-line-height,inherit);min-height:var(--_gcd-input-min-height,auto);padding:var(--_gcd-input-padding,0)}}._547d86373d02e108__textarea{box-sizing:var(--_gcd-textarea-box-sizing,border-box);overflow:var(--_gcd-textarea-overflow,auto);resize:var(--_gcd-textarea-resize,block)}._8c15fd0ed9f28ba4__div{outline:var(--_gcd-div-outline,0 solid transparent)}p._43cec3e1eec1066d__p{font-size:var(--_gcd-p-font-size,13px);line-height:var(--_gcd-p-line-height,1.5);margin:var(--_gcd-p-margin,0)}:is(h1,h2,h3,h4,h5,h6).e97669c6d9a38497__heading{color:var(--_gcd-heading-color,var(--wpds-color-foreground-content-neutral,#1e1e1e));font-size:var(--_gcd-heading-font-size,inherit);font-weight:var(--_gcd-heading-font-weight,var(--wpds-typography-font-weight-medium,499));margin:var(--_gcd-heading-margin,0)}._2c0831b0499dbd6e__a,._2c0831b0499dbd6e__a:is(:hover,:focus,:active){border-radius:var(--_gcd-a-border-radius,0);box-shadow:var(--_gcd-a-box-shadow,none);color:var(--_gcd-a-color,inherit);outline:var(--_gcd-a-outline,0 solid transparent);transition:var(--_gcd-a-transition,none)}");
2479
- var global_css_defense_default = {
2480
- "button": "_6defc79820e382c6__button",
2481
- "input": "d2cff2e5dea83bd1__input",
2482
- "textarea": "_547d86373d02e108__textarea",
2483
- "div": "_8c15fd0ed9f28ba4__div",
2484
- "p": "_43cec3e1eec1066d__p",
2485
- "heading": "e97669c6d9a38497__heading",
2486
- "a": "_2c0831b0499dbd6e__a"
2487
- };
2488
- var Button$1 = forwardRef$1(function Button2({ tone = "brand", variant = "solid", size = "default", className, focusableWhenDisabled = true, disabled, loading, loadingAnnouncement = __("Loading"), children, ...props }, ref) {
2489
- const mergedClassName = clsx(global_css_defense_default.button, resets_default["box-sizing"], focus_default["outset-ring--focus-except-active"], variant !== "unstyled" && style_default$2.button, style_default$2[`is-${tone}`], style_default$2[`is-${variant}`], style_default$2[`is-${size}`], loading && style_default$2["is-loading"], className);
2490
- useEffect$1(() => {
2491
- if (loading && loadingAnnouncement) speak(loadingAnnouncement);
2492
- }, [loading, loadingAnnouncement]);
2493
- return /* @__PURE__ */ jsx(Button$2, {
2494
- ref,
2495
- className: mergedClassName,
2496
- focusableWhenDisabled,
2497
- disabled: disabled ?? loading,
2498
- ...props,
2499
- children
2500
- });
2501
- });
2502
1451
  //#endregion
2503
- //#region ../../../node_modules/.pnpm/@wordpress+primitives@4.51.0_@types+react@18.3.28_react@18.3.1/node_modules/@wordpress/primitives/build-module/svg/index.mjs
2504
- var SVG = forwardRef$1(
2505
- /**
2506
- * @param {SVGProps} props isPressed indicates whether the SVG should appear as pressed.
2507
- * Other props will be passed through to svg component.
2508
- * @param {React.ForwardedRef<SVGSVGElement>} ref The forwarded ref to the SVG element.
2509
- *
2510
- * @return {React.JSX.Element} Stop component
2511
- */
2512
- ({ className, isPressed, ...props }, ref) => {
2513
- return /* @__PURE__ */ jsx("svg", {
2514
- ...props,
2515
- className: clsx(className, { "is-pressed": isPressed }) || void 0,
2516
- "aria-hidden": true,
2517
- focusable: false,
2518
- ref
1452
+ //#region src/providers/chart-context/hooks/use-chart-registration.ts
1453
+ const useChartRegistration = ({ chartId, legendItems, chartType, isDataValid, metadata }) => {
1454
+ const { registerChart, unregisterChart } = useGlobalChartsContext();
1455
+ const stableLegendItems = useDeepMemo(legendItems);
1456
+ const memoizedMetadata = useMemo(() => metadata, [metadata]);
1457
+ useEffect(() => {
1458
+ if (isDataValid) registerChart(chartId, {
1459
+ legendItems: stableLegendItems,
1460
+ chartType,
1461
+ metadata: memoizedMetadata
2519
1462
  });
2520
- }
2521
- );
2522
- SVG.displayName = "SVG";
2523
- //#endregion
2524
- //#region ../../../node_modules/.pnpm/@wordpress+ui@0.17.0_@types+react@18.3.28_date-fns@4.1.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/ui/build-module/icon/icon.mjs
2525
- var Icon$2 = forwardRef$1(function Icon2({ icon, size = 24, ...restProps }, ref) {
2526
- return /* @__PURE__ */ jsx(SVG, {
2527
- ref,
2528
- ...icon.props,
2529
- ...restProps,
2530
- width: size,
2531
- height: size
2532
- });
2533
- });
2534
- //#endregion
2535
- //#region ../../../node_modules/.pnpm/@wordpress+ui@0.17.0_@types+react@18.3.28_date-fns@4.1.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/ui/build-module/button/icon.mjs
2536
- var STYLE_HASH_ATTRIBUTE$1 = "data-wp-hash";
2537
- function getRuntime$1() {
2538
- const globalScope = globalThis;
2539
- if (globalScope.__wpStyleRuntime) return globalScope.__wpStyleRuntime;
2540
- globalScope.__wpStyleRuntime = {
2541
- documents: /* @__PURE__ */ new Map(),
2542
- styles: /* @__PURE__ */ new Map(),
2543
- injectedStyles: /* @__PURE__ */ new WeakMap()
2544
- };
2545
- if (typeof document !== "undefined") registerDocument$1(document);
2546
- return globalScope.__wpStyleRuntime;
2547
- }
2548
- function documentContainsStyleHash$1(targetDocument, hash) {
2549
- if (!targetDocument.head) return false;
2550
- for (const style of targetDocument.head.querySelectorAll(`style[${STYLE_HASH_ATTRIBUTE$1}]`)) if (style.getAttribute(STYLE_HASH_ATTRIBUTE$1) === hash) return true;
2551
- return false;
2552
- }
2553
- function injectStyle$1(targetDocument, hash, css) {
2554
- if (!targetDocument.head) return;
2555
- const runtime = getRuntime$1();
2556
- let injectedStyles = runtime.injectedStyles.get(targetDocument);
2557
- if (!injectedStyles) {
2558
- injectedStyles = /* @__PURE__ */ new Set();
2559
- runtime.injectedStyles.set(targetDocument, injectedStyles);
2560
- }
2561
- if (injectedStyles.has(hash)) return;
2562
- if (documentContainsStyleHash$1(targetDocument, hash)) {
2563
- injectedStyles.add(hash);
2564
- return;
2565
- }
2566
- const style = targetDocument.createElement("style");
2567
- style.setAttribute(STYLE_HASH_ATTRIBUTE$1, hash);
2568
- style.appendChild(targetDocument.createTextNode(css));
2569
- targetDocument.head.appendChild(style);
2570
- injectedStyles.add(hash);
2571
- }
2572
- function registerDocument$1(targetDocument) {
2573
- const runtime = getRuntime$1();
2574
- runtime.documents.set(targetDocument, (runtime.documents.get(targetDocument) ?? 0) + 1);
2575
- for (const [hash, css] of runtime.styles) injectStyle$1(targetDocument, hash, css);
2576
- return () => {
2577
- const count = runtime.documents.get(targetDocument);
2578
- if (count === void 0) return;
2579
- if (count <= 1) {
2580
- runtime.documents.delete(targetDocument);
2581
- return;
2582
- }
2583
- runtime.documents.set(targetDocument, count - 1);
2584
- };
2585
- }
2586
- function registerStyle$1(hash, css) {
2587
- const runtime = getRuntime$1();
2588
- runtime.styles.set(hash, css);
2589
- for (const targetDocument of runtime.documents.keys()) injectStyle$1(targetDocument, hash, css);
2590
- }
2591
- if (typeof process === "undefined" || process.env.NODE_ENV !== "test") registerStyle$1("4c317b0736", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._97b0fc33c028be1a__button,.abbb272e2ce49bd6__is-unstyled{appearance:none;padding:0}._97b0fc33c028be1a__button{--wp-ui-button-font-weight:var(--wpds-typography-font-weight-medium,499);--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-strong,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-strong-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 93%,#000));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand-strong,#fff);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-strong-active,#fff);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-strong-disabled,#8d8d8d);--wp-ui-button-padding-block:var(--wpds-dimension-padding-xs,4px);--wp-ui-button-padding-inline:var(--wpds-dimension-padding-md,12px);--wp-ui-button-height:var(--wpds-dimension-size-lg,40px);--wp-ui-button-aspect-ratio:auto;--wp-ui-button-font-size:var(--wpds-typography-font-size-md,13px);--wp-ui-button-min-width:calc(4ch + var(--wp-ui-button-padding-inline)*2);--wp-ui-button-icon-margin:calc((var(--wpds-dimension-size-2xs, 16px) - var(--wpds-dimension-size-sm, 24px))/2);--wp-ui-button-border-color:var(--wp-ui-button-background-color);--wp-ui-button-border-color-active:var(--wp-ui-button-background-color-active);--wp-ui-button-border-color-disabled:var(--wp-ui-button-background-color-disabled);--_gcd-button-font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,\"Segoe UI\",\"Roboto\",\"Oxygen-Sans\",\"Ubuntu\",\"Cantarell\",\"Helvetica Neue\",sans-serif);--_gcd-button-font-size:var(--wp-ui-button-font-size);--_gcd-button-font-weight:var(--wp-ui-button-font-weight);align-items:center;aspect-ratio:var(--wp-ui-button-aspect-ratio);background-clip:padding-box;background-color:var(--wp-ui-button-background-color);border-color:var(--wp-ui-button-border-color);border-radius:var(--wpds-border-radius-sm,2px);border-style:solid;border-width:1px;color:var(--wp-ui-button-foreground-color);display:inline-flex;font-family:var(--wpds-typography-font-family-body,-apple-system,system-ui,\"Segoe UI\",\"Roboto\",\"Oxygen-Sans\",\"Ubuntu\",\"Cantarell\",\"Helvetica Neue\",sans-serif);font-size:var(--wp-ui-button-font-size);font-weight:var(--wp-ui-button-font-weight);gap:var(--wpds-dimension-gap-sm,8px);justify-content:center;line-height:var(--wpds-typography-line-height-sm,20px);max-width:100%;min-height:var(--wp-ui-button-height);min-width:var(--wp-ui-button-min-width);overflow-wrap:anywhere;padding-block:var(--wp-ui-button-padding-block);padding-inline:var(--wp-ui-button-padding-inline);position:relative;text-align:center;text-decoration:none;&:not([data-disabled]){cursor:var(--wpds-cursor-control,pointer)}@media not (prefers-reduced-motion){transition:color .1s ease-out;*{transition:opacity .1s ease-out}}&[href]{cursor:pointer}[href]{color:inherit;text-decoration:inherit}&:not([data-disabled]):is(:hover,:active,:focus){background-color:var(--wp-ui-button-background-color-active);border-color:var(--wp-ui-button-border-color-active);color:var(--wp-ui-button-foreground-color-active)}&[data-disabled]:not(._914b42f315c0e580__is-loading){background-color:var(--wp-ui-button-background-color-disabled);border-color:var(--wp-ui-button-border-color-disabled);color:var(--wp-ui-button-foreground-color-disabled);@media (forced-colors:active){border-bottom-color:GrayText;border-left-color:GrayText;border-right-color:GrayText;border-top-color:GrayText;color:GrayText}}&:before{aspect-ratio:1;border:var(--wpds-border-width-focus,var(--wp-admin-border-width-focus,2px)) solid;border-block-end-color:transparent;border-block-start-color:var(--wp-ui-button-foreground-color);border-inline-end-color:var(--wp-ui-button-foreground-color);border-inline-start-color:transparent;border-radius:50%;box-sizing:border-box;content:\"\";display:block;height:var(--wp-ui-button-font-size);inset-inline-start:50%;opacity:0;pointer-events:none;position:absolute;top:50%;transform:translate(-50%,-50%);@media not (prefers-reduced-motion){transition:opacity .1s ease-out}@media (forced-colors:active){border-block-end-style:none;border-bottom-color:ButtonText;border-inline-start-style:none;border-left-color:ButtonText;border-right-color:ButtonText;border-top-color:ButtonText}}}._908205475f9f2a92__is-small{--wp-ui-button-padding-block:0;--wp-ui-button-padding-inline:var(--wpds-dimension-padding-sm,8px);--wp-ui-button-height:var(--wpds-dimension-size-sm,24px)}._9f6fc6553aeb36fe__icon{margin:var(--wp-ui-button-icon-margin)}.dd460c965226cc77__is-brand{&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 52%,#000));--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-brand-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-brand,var(--wp-admin-theme-color,#3858e9));--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-brand-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 85%,#000));--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-brand-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal{--wp-ui-button-background-color:var(--wpds-color-background-interactive-brand-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-brand-weak-active,color-mix(in oklch,var(--wp-admin-theme-color,#3858e9) 12%,#fff));--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-brand-weak-disabled,#0000)}}.e722a8f96726aa99__is-neutral{&.ad0619a3217c6a5b__is-minimal[aria-pressed=true],&.b50b3358c5fb4d0b__is-solid{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-strong,#2d2d2d);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-strong-active,#1e1e1e);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-strong-disabled,#e6e6e6);--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral-strong,#f0f0f0);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-strong-active,#f0f0f0);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-strong-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline,&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-foreground-color:var(--wpds-color-foreground-interactive-neutral,#1e1e1e);--wp-ui-button-foreground-color-active:var(--wpds-color-foreground-interactive-neutral-active,#1e1e1e);--wp-ui-button-foreground-color-disabled:var(--wpds-color-foreground-interactive-neutral-disabled,#8d8d8d)}&._62d5a778b7b258ee__is-outline{--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000);--wp-ui-button-border-color:var(--wpds-color-stroke-interactive-neutral,#8d8d8d);--wp-ui-button-border-color-active:var(--wpds-color-stroke-interactive-neutral-active,#6e6e6e);--wp-ui-button-border-color-disabled:var(--wpds-color-stroke-interactive-neutral-disabled,#dbdbdb)}&.ad0619a3217c6a5b__is-minimal:not([aria-pressed=true]){--wp-ui-button-background-color:var(--wpds-color-background-interactive-neutral-weak,#0000);--wp-ui-button-background-color-active:var(--wpds-color-background-interactive-neutral-weak-active,#ededed);--wp-ui-button-background-color-disabled:var(--wpds-color-background-interactive-neutral-weak-disabled,#0000)}}.abbb272e2ce49bd6__is-unstyled{background:none;border:none;min-width:unset}.cf59cf1b69629838__is-compact{--wp-ui-button-height:var(--wpds-dimension-size-md,32px)}._914b42f315c0e580__is-loading:not(.abbb272e2ce49bd6__is-unstyled){color:transparent;&:not([data-disabled]):is(:hover,:active,:focus){color:transparent}@media (forced-colors:active){color:ButtonFace}*{opacity:0}&:before{opacity:1;transition-delay:.05s;@media not (prefers-reduced-motion){animation:_5a1d53da6f830c8d__loading-animation 1s linear infinite}}}}@keyframes _5a1d53da6f830c8d__loading-animation{0%{transform:translate(-50%,-50%) rotate(0deg)}to{transform:translate(-50%,-50%) rotate(1turn)}}}");
2592
- var style_default$1 = {
2593
- "button": "_97b0fc33c028be1a__button",
2594
- "is-unstyled": "abbb272e2ce49bd6__is-unstyled",
2595
- "is-loading": "_914b42f315c0e580__is-loading",
2596
- "is-small": "_908205475f9f2a92__is-small",
2597
- "icon": "_9f6fc6553aeb36fe__icon",
2598
- "is-brand": "dd460c965226cc77__is-brand",
2599
- "is-outline": "_62d5a778b7b258ee__is-outline",
2600
- "is-minimal": "ad0619a3217c6a5b__is-minimal",
2601
- "is-neutral": "e722a8f96726aa99__is-neutral",
2602
- "is-solid": "b50b3358c5fb4d0b__is-solid",
2603
- "is-compact": "cf59cf1b69629838__is-compact",
2604
- "loading-animation": "_5a1d53da6f830c8d__loading-animation"
2605
- };
2606
- var ButtonIcon = forwardRef$1(function ButtonIcon2({ className, icon, ...props }, ref) {
2607
- return /* @__PURE__ */ jsx(Icon$2, {
2608
- ref,
2609
- icon,
2610
- className: clsx(style_default$1.icon, className),
2611
- size: 24,
2612
- ...props
2613
- });
2614
- });
1463
+ return () => {
1464
+ unregisterChart(chartId);
1465
+ };
1466
+ }, [
1467
+ chartId,
1468
+ stableLegendItems,
1469
+ chartType,
1470
+ memoizedMetadata,
1471
+ isDataValid
1472
+ ]);
1473
+ };
2615
1474
  //#endregion
2616
- //#region ../../../node_modules/.pnpm/@wordpress+ui@0.17.0_@types+react@18.3.28_date-fns@4.1.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/ui/build-module/button/index.mjs
2617
- ButtonIcon.displayName = "Button.Icon";
2618
- var Button = Object.assign(Button$1, {
1475
+ //#region src/providers/chart-context/hooks/use-global-charts-theme.ts
2619
1476
  /**
2620
- * An icon component specifically designed to work well when rendered inside
2621
- * a `Button` component.
1477
+ * Hook to get the global chart theme from GlobalChartsProvider
1478
+ *
1479
+ * @return The global chart theme
2622
1480
  */
2623
- Icon: ButtonIcon });
2624
- //#endregion
2625
- //#region ../../../node_modules/.pnpm/@wordpress+ui@0.17.0_@types+react@18.3.28_date-fns@4.1.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/ui/build-module/stack/stack.mjs
2626
- var STYLE_HASH_ATTRIBUTE = "data-wp-hash";
2627
- function getRuntime() {
2628
- const globalScope = globalThis;
2629
- if (globalScope.__wpStyleRuntime) return globalScope.__wpStyleRuntime;
2630
- globalScope.__wpStyleRuntime = {
2631
- documents: /* @__PURE__ */ new Map(),
2632
- styles: /* @__PURE__ */ new Map(),
2633
- injectedStyles: /* @__PURE__ */ new WeakMap()
2634
- };
2635
- if (typeof document !== "undefined") registerDocument(document);
2636
- return globalScope.__wpStyleRuntime;
2637
- }
2638
- function documentContainsStyleHash(targetDocument, hash) {
2639
- if (!targetDocument.head) return false;
2640
- for (const style of targetDocument.head.querySelectorAll(`style[${STYLE_HASH_ATTRIBUTE}]`)) if (style.getAttribute(STYLE_HASH_ATTRIBUTE) === hash) return true;
2641
- return false;
2642
- }
2643
- function injectStyle(targetDocument, hash, css) {
2644
- if (!targetDocument.head) return;
2645
- const runtime = getRuntime();
2646
- let injectedStyles = runtime.injectedStyles.get(targetDocument);
2647
- if (!injectedStyles) {
2648
- injectedStyles = /* @__PURE__ */ new Set();
2649
- runtime.injectedStyles.set(targetDocument, injectedStyles);
2650
- }
2651
- if (injectedStyles.has(hash)) return;
2652
- if (documentContainsStyleHash(targetDocument, hash)) {
2653
- injectedStyles.add(hash);
2654
- return;
2655
- }
2656
- const style = targetDocument.createElement("style");
2657
- style.setAttribute(STYLE_HASH_ATTRIBUTE, hash);
2658
- style.appendChild(targetDocument.createTextNode(css));
2659
- targetDocument.head.appendChild(style);
2660
- injectedStyles.add(hash);
2661
- }
2662
- function registerDocument(targetDocument) {
2663
- const runtime = getRuntime();
2664
- runtime.documents.set(targetDocument, (runtime.documents.get(targetDocument) ?? 0) + 1);
2665
- for (const [hash, css] of runtime.styles) injectStyle(targetDocument, hash, css);
2666
- return () => {
2667
- const count = runtime.documents.get(targetDocument);
2668
- if (count === void 0) return;
2669
- if (count <= 1) {
2670
- runtime.documents.delete(targetDocument);
2671
- return;
2672
- }
2673
- runtime.documents.set(targetDocument, count - 1);
2674
- };
2675
- }
2676
- function registerStyle(hash, css) {
2677
- const runtime = getRuntime();
2678
- runtime.styles.set(hash, css);
2679
- for (const targetDocument of runtime.documents.keys()) injectStyle(targetDocument, hash, css);
2680
- }
2681
- if (typeof process === "undefined" || process.env.NODE_ENV !== "test") registerStyle("32aba35fe1", "@layer wp-ui{@layer utilities, components, compositions, overrides;@layer components{._19ce0419607e1896__stack{display:flex}}}");
2682
- var style_default = { "stack": "_19ce0419607e1896__stack" };
2683
- var gapTokens = {
2684
- xs: "var(--wpds-dimension-gap-xs, 4px)",
2685
- sm: "var(--wpds-dimension-gap-sm, 8px)",
2686
- md: "var(--wpds-dimension-gap-md, 12px)",
2687
- lg: "var(--wpds-dimension-gap-lg, 16px)",
2688
- xl: "var(--wpds-dimension-gap-xl, 24px)",
2689
- "2xl": "var(--wpds-dimension-gap-2xl, 32px)",
2690
- "3xl": "var(--wpds-dimension-gap-3xl, 40px)"
2691
- };
2692
- var Stack = forwardRef$1(function Stack2({ direction, gap, align, justify, wrap, render, ...props }, ref) {
2693
- return useRender({
2694
- render,
2695
- ref,
2696
- props: mergeProps(props, {
2697
- style: {
2698
- gap: gap && gapTokens[gap],
2699
- alignItems: align,
2700
- justifyContent: justify,
2701
- flexDirection: direction,
2702
- flexWrap: wrap
2703
- },
2704
- className: style_default.stack
2705
- })
2706
- });
2707
- });
1481
+ const useGlobalChartsTheme = () => {
1482
+ return useContext(GlobalChartsContext)?.theme ?? defaultTheme;
1483
+ };
2708
1484
  //#endregion
2709
1485
  //#region src/components/legend/utils/value-or-identity.ts
2710
1486
  /**
@@ -3486,30 +2262,130 @@ const getCurveType = (type, smoothing) => {
3486
2262
  default: return curveLinear;
3487
2263
  }
3488
2264
  };
3489
- const formatYearTick = (timestamp) => {
3490
- return new Date(timestamp).toLocaleDateString(void 0, { year: "numeric" });
3491
- };
3492
- const formatDateTick$1 = (timestamp) => {
3493
- return new Date(timestamp).toLocaleDateString(void 0, {
3494
- month: "short",
3495
- day: "numeric"
3496
- });
2265
+ const dateTimeFormat = (options) => {
2266
+ let formatter;
2267
+ return (timestamp) => {
2268
+ if (!Number.isFinite(Number(timestamp))) return new Date(timestamp).toLocaleDateString();
2269
+ formatter = formatter ?? new Intl.DateTimeFormat(void 0, options);
2270
+ return formatter.format(timestamp);
2271
+ };
3497
2272
  };
3498
- const formatHourTick = (timestamp) => {
3499
- return new Date(timestamp).toLocaleTimeString(void 0, {
3500
- hour: "numeric",
3501
- hour12: true
3502
- });
2273
+ const formatYearTick = dateTimeFormat({ year: "numeric" });
2274
+ const formatDateTick = dateTimeFormat({
2275
+ month: "short",
2276
+ day: "numeric"
2277
+ });
2278
+ const formatHourTick = dateTimeFormat({
2279
+ hour: "numeric",
2280
+ hour12: true
2281
+ });
2282
+ const formatMonthTick = dateTimeFormat({ month: "short" });
2283
+ const boundaryFormat = (isAnchor, atBoundary, between) => {
2284
+ const format = (timestamp) => isAnchor(new Date(timestamp)) ? atBoundary(timestamp) : between(timestamp);
2285
+ format.isAnchor = isAnchor;
2286
+ return format;
2287
+ };
2288
+ const formatDateOrHourTick = boundaryFormat((date) => date.getHours() === 0 && date.getMinutes() === 0, formatDateTick, formatHourTick);
2289
+ const formatMonthOrYearTick = boundaryFormat((date) => date.getMonth() === 0, formatYearTick, formatMonthTick);
2290
+ const getSpan = (sortedData) => {
2291
+ const bounds = sortedData.map((datom) => [datom.data.at(0)?.date, datom.data.at(-1)?.date]).filter(([first, last]) => first !== void 0 && last !== void 0);
2292
+ if (!bounds.length) return null;
2293
+ return {
2294
+ minX: Math.min(...bounds.map(([first]) => Number(first))),
2295
+ maxX: Math.max(...bounds.map(([, last]) => Number(last)))
2296
+ };
3503
2297
  };
3504
- const getFormatter = (sortedData) => {
3505
- const minX = Math.min(...sortedData.map((datom) => datom.data.at(0)?.date));
3506
- const maxX = Math.max(...sortedData.map((datom) => datom.data.at(-1)?.date));
3507
- if (Math.abs(differenceInHours(maxX, minX)) <= 24) return formatHourTick;
3508
- if (Math.abs(differenceInYears(maxX, minX)) <= 1) return formatDateTick$1;
3509
- return formatYearTick;
2298
+ const getPointSpacingInHours = (sortedData) => {
2299
+ return sortedData.reduce((spacing, datom) => datom.data.reduce((seriesSpacing, point, index) => {
2300
+ const previous = datom.data[index - 1];
2301
+ if (previous?.date === void 0 || point?.date === void 0) return seriesSpacing;
2302
+ return Math.min(seriesSpacing, Math.abs(differenceInHours(point.date, previous.date)));
2303
+ }, spacing), Number.POSITIVE_INFINITY);
2304
+ };
2305
+ const SUB_DAILY_SPACING_HOURS = 23;
2306
+ const MONTHLY_SPACING_HOURS = 672;
2307
+ const getBucketResolution = (sortedData, tickResolution) => {
2308
+ if (tickResolution) return tickResolution === "week" ? "day" : tickResolution;
2309
+ const spacingInHours = getPointSpacingInHours(sortedData);
2310
+ if (spacingInHours < SUB_DAILY_SPACING_HOURS) return "hour";
2311
+ if (!Number.isFinite(spacingInHours) || spacingInHours < MONTHLY_SPACING_HOURS) return "day";
2312
+ return spacingInHours < 12 * MONTHLY_SPACING_HOURS ? "month" : "year";
2313
+ };
2314
+ const getFormatter = (sortedData, tickResolution) => {
2315
+ const resolution = getBucketResolution(sortedData, tickResolution);
2316
+ if (resolution === "year") return formatYearTick;
2317
+ if (resolution === "month") return formatMonthOrYearTick;
2318
+ const span = getSpan(sortedData);
2319
+ if (!span) return formatDateTick;
2320
+ const diffInHours = Math.abs(differenceInHours(span.maxX, span.minX));
2321
+ if (resolution === "hour") {
2322
+ if (diffInHours <= 24) return formatHourTick;
2323
+ if (diffInHours <= 168) return formatDateOrHourTick;
2324
+ }
2325
+ return Math.abs(differenceInYears(span.maxX, span.minX)) <= 1 ? formatDateTick : formatYearTick;
2326
+ };
2327
+ const getAnchorIndices = (domain, isAnchor) => domain.reduce((indices, date, index) => {
2328
+ if (isAnchor(date)) indices.push(index);
2329
+ return indices;
2330
+ }, []);
2331
+ const getCandidateSteps = (length, maxTicks, anchorSpacing) => {
2332
+ const steps = /* @__PURE__ */ new Set();
2333
+ for (let count = maxTicks; count > 1; count--) {
2334
+ steps.add(Math.max(1, Math.floor((length - 1) / (count - 1))));
2335
+ steps.add(Math.max(1, Math.ceil((length - 1) / (count - 1))));
2336
+ }
2337
+ if (anchorSpacing) {
2338
+ for (let divisor = 1; divisor <= anchorSpacing; divisor++) if (anchorSpacing % divisor === 0) steps.add(anchorSpacing / divisor);
2339
+ const minStep = Math.floor((length - 1) / Math.max(1, maxTicks)) + 1;
2340
+ steps.add(Math.ceil(minStep / anchorSpacing) * anchorSpacing);
2341
+ }
2342
+ return steps;
2343
+ };
2344
+ /**
2345
+ * Tick values for a band time axis.
2346
+ *
2347
+ * visx samples a band domain by index from offset zero, blind to which labels
2348
+ * carry a boundary and without collapsing repeats — so the tick that prints the
2349
+ * year or the date often isn't sampled at all, and a long series can show the
2350
+ * same label twice. Choose the values instead: sweep the evenly spaced
2351
+ * candidates, including those that step from anchor to anchor, and keep the one
2352
+ * that reaches the most anchors without thinning the axis or putting two
2353
+ * identical labels side by side.
2354
+ *
2355
+ * @param domain - Band domain, in axis order.
2356
+ * @param tickFormatter - Formatter the axis will render these values with.
2357
+ * @param maxTicks - Most ticks the axis should carry.
2358
+ * @return Values to hand the axis as `tickValues`.
2359
+ */
2360
+ const getBandTickValues = (domain, tickFormatter, maxTicks) => {
2361
+ if (!domain.length) return [];
2362
+ const { isAnchor } = tickFormatter;
2363
+ const anchorIndices = isAnchor ? getAnchorIndices(domain, isAnchor) : [];
2364
+ const domainLabels = domain.map((date) => tickFormatter(date.getTime()));
2365
+ const candidates = [];
2366
+ const consider = (indices) => {
2367
+ if (!indices.length || indices.length > maxTicks) return;
2368
+ if (!indices.some((index, position) => position > 0 && domainLabels[index] === domainLabels[indices[position - 1]])) candidates.push(indices);
2369
+ };
2370
+ const anchorSpacing = anchorIndices.length > 1 ? anchorIndices[1] - anchorIndices[0] : null;
2371
+ for (const step of getCandidateSteps(domain.length, maxTicks, anchorSpacing)) for (let offset = 0; offset < step; offset++) {
2372
+ const indices = [];
2373
+ for (let index = offset; index < domain.length; index += step) indices.push(index);
2374
+ consider(indices);
2375
+ }
2376
+ for (let stride = 1; stride <= anchorIndices.length; stride++) consider(anchorIndices.filter((_, position) => position % stride === 0));
2377
+ if (!candidates.length) return [domain[0]];
2378
+ const densest = candidates.reduce((most, indices) => Math.max(most, indices.length), 0);
2379
+ const anchorsIn = (indices) => isAnchor ? indices.filter((index) => isAnchor(domain[index])).length : 0;
2380
+ return candidates.filter((indices) => indices.length >= densest - 1).reduce((chosen, indices) => {
2381
+ const gain = anchorsIn(indices) - anchorsIn(chosen);
2382
+ return gain > 0 || gain === 0 && indices.length > chosen.length ? indices : chosen;
2383
+ }).map((index) => domain[index]);
3510
2384
  };
3511
2385
  const guessOptimalNumTicks = (data, chartWidth, tickFormatter) => {
3512
- const xScale = scaleTime({ domain: [Math.min(...data.map((datom) => datom.data.at(0)?.date)), Math.max(...data.map((datom) => datom.data.at(-1)?.date))] });
2386
+ const span = getSpan(data);
2387
+ if (!span) return 1;
2388
+ const xScale = scaleTime({ domain: [span.minX, span.maxX] });
3513
2389
  const upperBound = Math.min(data[0]?.data.length || 3, Math.ceil(chartWidth / X_TICK_WIDTH));
3514
2390
  let secondBestGuess = 1;
3515
2391
  for (let numTicks = upperBound; numTicks > 1; --numTicks) {
@@ -3742,14 +2618,8 @@ function ZoomClip({ active, chartId, children }) {
3742
2618
  }
3743
2619
  /**
3744
2620
  * Visible icon-only reset control rendered as an HTML overlay on top of the
3745
- * chart container, using the WPDS `Button`. The host should wrap its SVG in a
3746
- * `position: relative` container so the button anchors correctly.
3747
- *
3748
- * `IconButton` would be the natural fit, but it renders a Base UI tooltip whose
3749
- * CommonJS `use-sync-external-store` dependency makes Rolldown emit a dynamic
3750
- * `require()` into `dist`, which throws on evaluation in WordPress Script
3751
- * Module consumers. `Button` gives the same treatment without that dependency;
3752
- * the tooltip is replaced by `aria-label` + `title`.
2621
+ * chart container, using the WPDS `IconButton`. The host should wrap its SVG in
2622
+ * a `position: relative` container so the button anchors correctly.
3753
2623
  *
3754
2624
  * @param props - Props.
3755
2625
  * @param props.onClick - Click handler. Typically the `reset` from `useXZoom`.
@@ -3759,17 +2629,15 @@ function ZoomResetButton({ onClick }) {
3759
2629
  const stopActivationKeys = useCallback((event) => {
3760
2630
  if (event.key === "Enter" || event.key === " ") event.stopPropagation();
3761
2631
  }, []);
3762
- const label = __("Reset zoom", "jetpack-charts");
3763
- return /* @__PURE__ */ jsx(Button, {
2632
+ return /* @__PURE__ */ jsx(IconButton, {
3764
2633
  className: x_zoom_module_default["x-zoom__reset"],
3765
2634
  onKeyDown: stopActivationKeys,
3766
- "aria-label": label,
3767
- title: label,
2635
+ label: __("Reset zoom", "jetpack-charts"),
3768
2636
  variant: "outline",
3769
2637
  tone: "neutral",
3770
2638
  size: "small",
3771
2639
  onClick,
3772
- children: /* @__PURE__ */ jsx(Button.Icon, { icon: /* @__PURE__ */ jsx("svg", {
2640
+ icon: /* @__PURE__ */ jsx("svg", {
3773
2641
  viewBox: "0 0 24 24",
3774
2642
  fill: "none",
3775
2643
  stroke: "currentColor",
@@ -3800,7 +2668,7 @@ function ZoomResetButton({ onClick }) {
3800
2668
  })
3801
2669
  ]
3802
2670
  })
3803
- }) })
2671
+ })
3804
2672
  });
3805
2673
  }
3806
2674
  //#endregion
@@ -4295,8 +3163,8 @@ const LineChartInternal = forwardRef(({ data, chartId: providedChartId, width, h
4295
3163
  const legendShape = legend.shape ?? "line";
4296
3164
  const legendPosition = legend.position ?? "bottom";
4297
3165
  const providerTheme = useGlobalChartsTheme();
4298
- const resolvedBackgroundColor = resolveCssVariable(providerTheme.backgroundColor) ?? providerTheme.backgroundColor;
4299
3166
  const theme = useXYChartTheme(data);
3167
+ const resolvedBackgroundColor = theme.backgroundColor ?? providerTheme.backgroundColor;
4300
3168
  const chartId = useChartId(providedChartId);
4301
3169
  const chartRef = useRef(null);
4302
3170
  const [selectedIndex, setSelectedIndex] = useState(void 0);
@@ -4372,7 +3240,8 @@ const LineChartInternal = forwardRef(({ data, chartId: providedChartId, width, h
4372
3240
  totalPoints: dataSorted[0]?.data.length || 0
4373
3241
  });
4374
3242
  const chartOptions = useMemo(() => {
4375
- const formatter = options?.axis?.x?.tickFormat || getFormatter(dataSorted);
3243
+ const { tickResolution, ...xAxisOptions } = options?.axis?.x ?? {};
3244
+ const formatter = xAxisOptions.tickFormat || getFormatter(dataSorted, tickResolution);
4376
3245
  return {
4377
3246
  axis: {
4378
3247
  x: {
@@ -4380,7 +3249,7 @@ const LineChartInternal = forwardRef(({ data, chartId: providedChartId, width, h
4380
3249
  numTicks: guessOptimalNumTicks(dataSorted, width, formatter),
4381
3250
  tickFormat: formatter,
4382
3251
  display: true,
4383
- ...options?.axis?.x
3252
+ ...xAxisOptions
4384
3253
  },
4385
3254
  y: {
4386
3255
  orientation: "left",
@@ -4846,7 +3715,8 @@ const AreaChartInternal = forwardRef(({ data, chartId: providedChartId, width, h
4846
3715
  rescaleYOnVisibility
4847
3716
  ]);
4848
3717
  const chartOptions = useMemo(() => {
4849
- const formatter = options?.axis?.x?.tickFormat || getFormatter(dataSorted);
3718
+ const { tickResolution, ...xAxisOptions } = options?.axis?.x ?? {};
3719
+ const formatter = xAxisOptions.tickFormat || getFormatter(dataSorted, tickResolution);
4850
3720
  return {
4851
3721
  axis: {
4852
3722
  x: {
@@ -4854,7 +3724,7 @@ const AreaChartInternal = forwardRef(({ data, chartId: providedChartId, width, h
4854
3724
  numTicks: guessOptimalNumTicks(dataSorted, width, formatter),
4855
3725
  tickFormat: formatter,
4856
3726
  display: true,
4857
- ...options?.axis?.x
3727
+ ...xAxisOptions
4858
3728
  },
4859
3729
  y: {
4860
3730
  orientation: "left",
@@ -5070,7 +3940,7 @@ const AreaChartInternal = forwardRef(({ data, chartId: providedChartId, width, h
5070
3940
  stacked,
5071
3941
  stackOffset,
5072
3942
  getElementStyles,
5073
- strokeColor: resolveCssVariable(providerTheme.backgroundColor) ?? providerTheme.backgroundColor
3943
+ strokeColor: theme.backgroundColor ?? providerTheme.backgroundColor
5074
3944
  })] }),
5075
3945
  /* @__PURE__ */ jsx(AreaChartScalesRef, {
5076
3946
  chartRef: internalChartRef,
@@ -5230,11 +4100,73 @@ const TruncatedYTickComponent = createTruncatedTickComponent("y");
5230
4100
  const BASE_BAND_PADDING = .2;
5231
4101
  /** Inner padding of the category band scale (the base gap between ticks). */
5232
4102
  const BASE_BAND_PADDING_INNER = .1;
5233
- const formatDateTick = (timestamp) => {
5234
- return new Date(timestamp).toLocaleDateString(void 0, {
5235
- month: "short",
4103
+ /** Ticks each axis carries unless the caller asks for a different count. */
4104
+ const DEFAULT_NUM_TICKS = 4;
4105
+ const ALL_RENDERED = () => true;
4106
+ const TOOLTIP_FORMAT_BY_RESOLUTION = {
4107
+ hour: {
4108
+ year: "numeric",
4109
+ month: "long",
4110
+ day: "numeric",
4111
+ hour: "numeric",
4112
+ hour12: true
4113
+ },
4114
+ day: {
4115
+ year: "numeric",
4116
+ month: "long",
5236
4117
  day: "numeric"
5237
- });
4118
+ },
4119
+ month: {
4120
+ year: "numeric",
4121
+ month: "long"
4122
+ },
4123
+ year: { year: "numeric" }
4124
+ };
4125
+ /**
4126
+ * Labels one bar's bucket, at the bucket's own granularity — finer than the
4127
+ * ticks whenever the overall time span coarsens the axis.
4128
+ *
4129
+ * @param data - Date-based series, already parsed and sorted by `useChartDataTransform`.
4130
+ * @param tickResolution - Caller-declared bucket resolution, when known.
4131
+ * @return Tooltip label formatter.
4132
+ */
4133
+ const getTooltipFormatter = (data, tickResolution) => {
4134
+ if (tickResolution === "week") return (timestamp) => sprintf(__("Week of %s", "jetpack-charts"), new Date(timestamp).toLocaleDateString(void 0, {
4135
+ year: "numeric",
4136
+ month: "long",
4137
+ day: "numeric"
4138
+ }));
4139
+ const format = TOOLTIP_FORMAT_BY_RESOLUTION[getBucketResolution(data, tickResolution)] ?? TOOLTIP_FORMAT_BY_RESOLUTION.day;
4140
+ return (timestamp) => new Date(timestamp).toLocaleString(void 0, format);
4141
+ };
4142
+ const identity = (label) => label;
4143
+ const byBucket = (format) => (bucket) => typeof bucket === "string" ? bucket : format(Number(bucket));
4144
+ const bucketAccessor = (d) => d?.label || d?.date;
4145
+ /**
4146
+ * The buckets the band axis can put a tick on.
4147
+ *
4148
+ * Built from the accessor visx is given, over the same series in the same order,
4149
+ * so that a tick value is a key the scale actually holds; `scaleBand` returns
4150
+ * `undefined` for one it does not, which parks the tick at the origin. Null
4151
+ * rather than a partial list when any bucket is labelled instead of dated.
4152
+ *
4153
+ * @param data - Every series handed to the chart.
4154
+ * @param isSeriesRendered - Whether visx mounts a series, i.e. the legend shows it.
4155
+ * @return Bucket dates in axis order, or null if the axis cannot be ticked by date.
4156
+ */
4157
+ const getBandDomain = (data, isSeriesRendered) => {
4158
+ const registry = {};
4159
+ for (const series of data) {
4160
+ if (series.options?.type === "comparison" || !isSeriesRendered(series)) continue;
4161
+ registry[series.label] = series;
4162
+ }
4163
+ const byTimestamp = /* @__PURE__ */ new Map();
4164
+ for (const key of Object.keys(registry)) for (const point of registry[key].data) {
4165
+ const bucket = bucketAccessor(point);
4166
+ if (!(bucket instanceof Date)) return null;
4167
+ if (!byTimestamp.has(bucket.getTime())) byTimestamp.set(bucket.getTime(), bucket);
4168
+ }
4169
+ return byTimestamp.size ? [...byTimestamp.values()] : null;
5238
4170
  };
5239
4171
  /**
5240
4172
  * Get the group padding of a scale.
@@ -5248,12 +4180,26 @@ const getGroupPadding = (scale) => {
5248
4180
  /**
5249
4181
  * Returns the merged options for the bar chart, including axis and scale configuration based on the orientation.
5250
4182
  *
5251
- * @param data - The data to be displayed in the chart.
5252
- * @param horizontal - Whether the chart is horizontal or vertical.
5253
- * @param options - The options for the chart.
4183
+ * @param data - The data to be displayed in the chart.
4184
+ * @param horizontal - Whether the chart is horizontal or vertical.
4185
+ * @param options - The options for the chart.
4186
+ * @param isSeriesRendered - Whether visx mounts a series, i.e. the legend shows it.
5254
4187
  * @return The merged options for the chart.
5255
4188
  */
5256
- function useBarChartOptions(data, horizontal, options = {}) {
4189
+ function useBarChartOptions(data, horizontal, options = {}, isSeriesRendered = ALL_RENDERED) {
4190
+ const stableOptions = useDeepMemo(options);
4191
+ const axisConfig = useMemo(() => {
4192
+ const { labelOverflow: xLabelOverflow, tickResolution: xTickResolution, ...xAxisOptions } = stableOptions.axis?.x || {};
4193
+ const { labelOverflow: yLabelOverflow, tickResolution: yTickResolution, ...yAxisOptions } = stableOptions.axis?.y || {};
4194
+ return {
4195
+ xLabelOverflow,
4196
+ yLabelOverflow,
4197
+ xAxisOptions,
4198
+ yAxisOptions,
4199
+ tickResolution: horizontal ? yTickResolution : xTickResolution
4200
+ };
4201
+ }, [stableOptions, horizontal]);
4202
+ const { tickResolution } = axisConfig;
5257
4203
  const defaultOptions = useMemo(() => {
5258
4204
  const bandScale = {
5259
4205
  type: "band",
@@ -5265,19 +4211,26 @@ function useBarChartOptions(data, horizontal, options = {}) {
5265
4211
  nice: true,
5266
4212
  zero: false
5267
4213
  };
5268
- const labelFormatter = data?.[0]?.data?.[0]?.label ? (label) => label : formatDateTick;
4214
+ const hasLabels = Boolean(data?.[0]?.data?.[0]?.label);
4215
+ const timeTickFormatter = hasLabels ? null : getFormatter(data, tickResolution);
4216
+ const labelFormatter = timeTickFormatter ? byBucket(timeTickFormatter) : identity;
4217
+ const tooltipDatumFormatter = hasLabels ? labelFormatter : byBucket(getTooltipFormatter(data, tickResolution));
5269
4218
  const valueFormatter = formatNumberCompact;
5270
- const labelAccessor = (d) => d?.label || d?.date;
4219
+ const bandDomain = timeTickFormatter ? getBandDomain(data, isSeriesRendered) : null;
5271
4220
  const valueAccessor = (d) => {
5272
4221
  const enhancedPoint = d;
5273
4222
  return enhancedPoint?.visualValue !== void 0 ? enhancedPoint.visualValue : d?.value;
5274
4223
  };
5275
4224
  return {
4225
+ timeAxis: bandDomain && timeTickFormatter && {
4226
+ domain: bandDomain,
4227
+ tickFormatter: timeTickFormatter
4228
+ },
5276
4229
  vertical: {
5277
4230
  xTickFormat: labelFormatter,
5278
4231
  yTickFormat: valueFormatter,
5279
- tooltipLabelFormatter: labelFormatter,
5280
- xAccessor: labelAccessor,
4232
+ tooltipLabelFormatter: tooltipDatumFormatter,
4233
+ xAccessor: bucketAccessor,
5281
4234
  yAccessor: valueAccessor,
5282
4235
  gridVisibility: "x",
5283
4236
  xScale: bandScale,
@@ -5286,20 +4239,24 @@ function useBarChartOptions(data, horizontal, options = {}) {
5286
4239
  horizontal: {
5287
4240
  xTickFormat: valueFormatter,
5288
4241
  yTickFormat: labelFormatter,
5289
- tooltipLabelFormatter: labelFormatter,
4242
+ tooltipLabelFormatter: tooltipDatumFormatter,
5290
4243
  xAccessor: valueAccessor,
5291
- yAccessor: labelAccessor,
4244
+ yAccessor: bucketAccessor,
5292
4245
  gridVisibility: "y",
5293
4246
  xScale: linearScale,
5294
4247
  yScale: bandScale
5295
4248
  }
5296
4249
  };
5297
- }, [data]);
4250
+ }, [
4251
+ data,
4252
+ tickResolution,
4253
+ isSeriesRendered
4254
+ ]);
5298
4255
  return useMemo(() => {
5299
4256
  const { xTickFormat, yTickFormat, tooltipLabelFormatter: defaultTooltipLabelFormatter, xAccessor, yAccessor, gridVisibility, xScale: baseXScale, yScale: baseYScale } = defaultOptions[horizontal ? "horizontal" : "vertical"];
5300
4257
  let valueScaleDomainOverride = {};
5301
4258
  if (data.some((s) => s.options?.type === "comparison")) {
5302
- if (!(!horizontal ? options.yScale?.domain : options.xScale?.domain)) {
4259
+ if (!(!horizontal ? stableOptions.yScale?.domain : stableOptions.xScale?.domain)) {
5303
4260
  const allValues = [];
5304
4261
  data.forEach((series) => {
5305
4262
  series.data.forEach((d) => {
@@ -5313,17 +4270,20 @@ function useBarChartOptions(data, horizontal, options = {}) {
5313
4270
  }
5314
4271
  const xScale = {
5315
4272
  ...baseXScale,
5316
- ...options.xScale || {},
4273
+ ...stableOptions.xScale || {},
5317
4274
  ...horizontal ? valueScaleDomainOverride : {}
5318
4275
  };
5319
4276
  const yScale = {
5320
4277
  ...baseYScale,
5321
- ...options.yScale || {},
4278
+ ...stableOptions.yScale || {},
5322
4279
  ...!horizontal ? valueScaleDomainOverride : {}
5323
4280
  };
5324
- const providedToolTipLabelFormatter = horizontal ? options.axis?.y?.tickFormat : options.axis?.x?.tickFormat;
5325
- const { labelOverflow: xLabelOverflow, ...xAxisOptions } = options.axis?.x || {};
5326
- const { labelOverflow: yLabelOverflow, ...yAxisOptions } = options.axis?.y || {};
4281
+ const { xLabelOverflow, yLabelOverflow, xAxisOptions, yAxisOptions } = axisConfig;
4282
+ const providedToolTipLabelFormatter = horizontal ? yAxisOptions.tickFormat : xAxisOptions.tickFormat;
4283
+ const { timeAxis } = defaultOptions;
4284
+ const dateAxisOptions = horizontal ? yAxisOptions : xAxisOptions;
4285
+ const bandTickValues = timeAxis && !dateAxisOptions.tickFormat ? getBandTickValues(timeAxis.domain, timeAxis.tickFormatter, dateAxisOptions.numTicks ?? DEFAULT_NUM_TICKS) : null;
4286
+ const dateAxisTickValues = bandTickValues ? { tickValues: bandTickValues } : {};
5327
4287
  return {
5328
4288
  gridVisibility,
5329
4289
  xScale,
@@ -5335,15 +4295,17 @@ function useBarChartOptions(data, horizontal, options = {}) {
5335
4295
  axis: {
5336
4296
  x: {
5337
4297
  orientation: "bottom",
5338
- numTicks: 4,
4298
+ numTicks: DEFAULT_NUM_TICKS,
5339
4299
  tickFormat: xTickFormat,
4300
+ ...horizontal ? {} : dateAxisTickValues,
5340
4301
  ...xLabelOverflow === "ellipsis" ? { tickComponent: TruncatedXTickComponent } : {},
5341
4302
  ...xAxisOptions
5342
4303
  },
5343
4304
  y: {
5344
4305
  orientation: "left",
5345
- numTicks: 4,
4306
+ numTicks: DEFAULT_NUM_TICKS,
5346
4307
  tickFormat: yTickFormat,
4308
+ ...horizontal ? dateAxisTickValues : {},
5347
4309
  ...yLabelOverflow === "ellipsis" ? { tickComponent: TruncatedYTickComponent } : {},
5348
4310
  ...yAxisOptions
5349
4311
  }
@@ -5353,7 +4315,8 @@ function useBarChartOptions(data, horizontal, options = {}) {
5353
4315
  };
5354
4316
  }, [
5355
4317
  defaultOptions,
5356
- options,
4318
+ axisConfig,
4319
+ stableOptions,
5357
4320
  horizontal,
5358
4321
  data
5359
4322
  ]);
@@ -5515,7 +4478,13 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height, class
5515
4478
  valueAxisLength: horizontal ? width : height
5516
4479
  });
5517
4480
  const legendItems = useChartLegendItems(dataSorted, useMemo(() => ({ collapseGroups: legendCollapseGroups }), [legendCollapseGroups]));
5518
- const chartOptions = useBarChartOptions(dataWithVisibleZeros, horizontal, options);
4481
+ const { getElementStyles, isSeriesVisible } = useGlobalChartsContext();
4482
+ const isSeriesRendered = useCallback((series) => !chartId || !legendInteractive || isSeriesVisible(chartId, series.label), [
4483
+ chartId,
4484
+ legendInteractive,
4485
+ isSeriesVisible
4486
+ ]);
4487
+ const chartOptions = useBarChartOptions(dataWithVisibleZeros, horizontal, options, isSeriesRendered);
5519
4488
  const defaultMargin = useChartMargin(height, chartOptions, dataSorted, theme, horizontal);
5520
4489
  const chartRef = useRef(null);
5521
4490
  const { legendChildren, nonLegendChildren } = useChartChildren(children, "BarChart");
@@ -5534,24 +4503,11 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height, class
5534
4503
  chartRef,
5535
4504
  totalPoints: Math.max(0, ...primarySeriesForNav.map((s) => s.data?.length || 0)) * primarySeriesForNav.length
5536
4505
  });
5537
- const { getElementStyles, isSeriesVisible } = useGlobalChartsContext();
5538
- const seriesWithVisibility = useMemo(() => {
5539
- if (!chartId || !legendInteractive) return dataWithVisibleZeros.map((series, index) => ({
5540
- series,
5541
- index,
5542
- isVisible: true
5543
- }));
5544
- return dataWithVisibleZeros.map((series, index) => ({
5545
- series,
5546
- index,
5547
- isVisible: isSeriesVisible(chartId, series.label)
5548
- }));
5549
- }, [
5550
- dataWithVisibleZeros,
5551
- chartId,
5552
- isSeriesVisible,
5553
- legendInteractive
5554
- ]);
4506
+ const seriesWithVisibility = useMemo(() => dataWithVisibleZeros.map((series, index) => ({
4507
+ series,
4508
+ index,
4509
+ isVisible: isSeriesRendered(series)
4510
+ })), [dataWithVisibleZeros, isSeriesRendered]);
5555
4511
  const allSeriesHidden = useMemo(() => {
5556
4512
  return seriesWithVisibility.every(({ isVisible }) => !isVisible);
5557
4513
  }, [seriesWithVisibility]);
@@ -7067,6 +6023,73 @@ const HeatmapChartResponsiveInner = (props) => /* @__PURE__ */ jsx(HeatmapChartW
7067
6023
  HeatmapChartResponsiveInner.displayName = "HeatmapChart";
7068
6024
  const HeatmapChartResponsive = attachSubComponents(withResponsive(HeatmapChartResponsiveInner), { Legend: HeatmapLegend });
7069
6025
  //#endregion
6026
+ //#region ../../../node_modules/.pnpm/is-plain-object@5.0.0/node_modules/is-plain-object/dist/is-plain-object.mjs
6027
+ /*!
6028
+ * is-plain-object <https://github.com/jonschlinkert/is-plain-object>
6029
+ *
6030
+ * Copyright (c) 2014-2017, Jon Schlinkert.
6031
+ * Released under the MIT License.
6032
+ */
6033
+ function isObject(o) {
6034
+ return Object.prototype.toString.call(o) === "[object Object]";
6035
+ }
6036
+ function isPlainObject(o) {
6037
+ var ctor, prot;
6038
+ if (isObject(o) === false) return false;
6039
+ ctor = o.constructor;
6040
+ if (ctor === void 0) return true;
6041
+ prot = ctor.prototype;
6042
+ if (isObject(prot) === false) return false;
6043
+ if (prot.hasOwnProperty("isPrototypeOf") === false) return false;
6044
+ return true;
6045
+ }
6046
+ //#endregion
6047
+ //#region ../../../node_modules/.pnpm/lower-case@2.0.2/node_modules/lower-case/dist.es2015/index.js
6048
+ /**
6049
+ * Lower case as a function.
6050
+ */
6051
+ function lowerCase(str) {
6052
+ return str.toLowerCase();
6053
+ }
6054
+ //#endregion
6055
+ //#region ../../../node_modules/.pnpm/no-case@3.0.4/node_modules/no-case/dist.es2015/index.js
6056
+ var DEFAULT_SPLIT_REGEXP = [/([a-z0-9])([A-Z])/g, /([A-Z])([A-Z][a-z])/g];
6057
+ var DEFAULT_STRIP_REGEXP = /[^A-Z0-9]+/gi;
6058
+ /**
6059
+ * Normalize the string into something other libraries can manipulate easier.
6060
+ */
6061
+ function noCase(input, options) {
6062
+ if (options === void 0) options = {};
6063
+ var _a = options.splitRegexp, splitRegexp = _a === void 0 ? DEFAULT_SPLIT_REGEXP : _a, _b = options.stripRegexp, stripRegexp = _b === void 0 ? DEFAULT_STRIP_REGEXP : _b, _c = options.transform, transform = _c === void 0 ? lowerCase : _c, _d = options.delimiter, delimiter = _d === void 0 ? " " : _d;
6064
+ var result = replace$1(replace$1(input, splitRegexp, "$1\0$2"), stripRegexp, "\0");
6065
+ var start = 0;
6066
+ var end = result.length;
6067
+ while (result.charAt(start) === "\0") start++;
6068
+ while (result.charAt(end - 1) === "\0") end--;
6069
+ return result.slice(start, end).split("\0").map(transform).join(delimiter);
6070
+ }
6071
+ /**
6072
+ * Replace `re` in the input string with the replacement value.
6073
+ */
6074
+ function replace$1(input, re, value) {
6075
+ if (re instanceof RegExp) return input.replace(re, value);
6076
+ return re.reduce(function(input, re) {
6077
+ return input.replace(re, value);
6078
+ }, input);
6079
+ }
6080
+ //#endregion
6081
+ //#region ../../../node_modules/.pnpm/dot-case@3.0.4/node_modules/dot-case/dist.es2015/index.js
6082
+ function dotCase(input, options) {
6083
+ if (options === void 0) options = {};
6084
+ return noCase(input, __assign({ delimiter: "." }, options));
6085
+ }
6086
+ //#endregion
6087
+ //#region ../../../node_modules/.pnpm/param-case@3.0.4/node_modules/param-case/dist.es2015/index.js
6088
+ function paramCase(input, options) {
6089
+ if (options === void 0) options = {};
6090
+ return dotCase(input, __assign({ delimiter: "-" }, options));
6091
+ }
6092
+ //#endregion
7070
6093
  //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/utils/hooks/use-update-effect.mjs
7071
6094
  function useUpdateEffect(effect, deps) {
7072
6095
  const mountedRef = useRef$1(false);
@@ -8931,10 +7954,10 @@ var require_es6 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
8931
7954
  };
8932
7955
  }));
8933
7956
  //#endregion
8934
- //#region ../../../node_modules/.pnpm/@wordpress+warning@3.51.0/node_modules/@wordpress/warning/build-module/utils.mjs
7957
+ //#region ../../../node_modules/.pnpm/@wordpress+warning@3.52.0/node_modules/@wordpress/warning/build-module/utils.mjs
8935
7958
  var logged = /* @__PURE__ */ new Set();
8936
7959
  //#endregion
8937
- //#region ../../../node_modules/.pnpm/@wordpress+warning@3.51.0/node_modules/@wordpress/warning/build-module/index.mjs
7960
+ //#region ../../../node_modules/.pnpm/@wordpress+warning@3.52.0/node_modules/@wordpress/warning/build-module/index.mjs
8938
7961
  function isDev() {
8939
7962
  return globalThis.SCRIPT_DEBUG === true;
8940
7963
  }