@automattic/charts 2.0.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/TOKENS.md +107 -48
- package/dist/index.cjs +294 -110
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +97 -43
- package/dist/index.d.cts +40 -35
- package/dist/index.d.ts +40 -35
- package/dist/index.js +292 -111
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/charts/area-chart/area-chart.module.scss +8 -3
- package/src/charts/area-chart/area-chart.tsx +1 -1
- package/src/charts/bar-chart/bar-chart.module.scss +14 -6
- package/src/charts/conversion-funnel-chart/conversion-funnel-chart.module.scss +17 -12
- package/src/charts/conversion-funnel-chart/conversion-funnel-chart.tsx +107 -86
- package/src/charts/conversion-funnel-chart/test/chart-scope.test.tsx +36 -0
- package/src/charts/geo-chart/geo-chart.tsx +12 -4
- package/src/charts/heatmap-chart/heatmap-chart.module.scss +13 -9
- package/src/charts/heatmap-chart/heatmap-chart.tsx +12 -5
- package/src/charts/leaderboard-chart/leaderboard-chart.module.scss +13 -7
- package/src/charts/leaderboard-chart/types.ts +0 -2
- package/src/charts/line-chart/line-chart.module.scss +10 -5
- package/src/charts/line-chart/line-chart.tsx +1 -1
- package/src/charts/line-chart/private/line-chart-annotation.tsx +4 -4
- package/src/charts/pie-chart/pie-chart.tsx +4 -1
- package/src/charts/pie-semi-circle-chart/pie-semi-circle-chart.tsx +4 -1
- package/src/charts/private/svg-empty-state/svg-empty-state.module.scss +1 -1
- package/src/charts/private/with-responsive/test/with-responsive.test.tsx +16 -0
- package/src/charts/private/with-responsive/with-responsive.tsx +18 -11
- package/src/charts/private/x-zoom/x-zoom.module.scss +3 -3
- package/src/components/legend/private/base-legend.tsx +3 -1
- package/src/components/tooltip/accessible-tooltip.tsx +4 -2
- package/src/components/tooltip/base-tooltip.tsx +8 -1
- package/src/components/trend-indicator/test/trend-indicator.test.tsx +20 -0
- package/src/components/trend-indicator/trend-indicator.module.scss +3 -6
- package/src/components/trend-indicator/trend-indicator.tsx +3 -0
- package/src/hooks/test/use-xychart-theme-provider-override.test.tsx +28 -0
- package/src/hooks/test/use-xychart-theme-style-reads.test.tsx +19 -13
- package/src/hooks/test/use-xychart-theme.test.tsx +25 -0
- package/src/hooks/use-xychart-theme.ts +6 -4
- package/src/index.ts +9 -2
- package/src/providers/chart-context/global-charts-provider.tsx +35 -12
- package/src/providers/chart-context/private/theme-override-vars.ts +87 -0
- package/src/providers/chart-context/private/with-catalog-pointers.ts +50 -0
- package/src/providers/chart-context/test/chart-context.test.tsx +0 -40
- package/src/providers/chart-context/test/chart-scope-class.test.tsx +19 -0
- package/src/providers/chart-context/test/sparse-theme.test.ts +35 -0
- package/src/providers/chart-context/test/theme-override-vars-guard.test.tsx +29 -0
- package/src/providers/chart-context/test/theme-override-vars.test.ts +118 -0
- package/src/providers/chart-context/test/with-catalog-pointers.test.ts +47 -0
- package/src/providers/chart-context/themes.ts +18 -27
- package/src/providers/chart-context/types.ts +0 -3
- package/src/providers/chart-scope/chart-scope-context.ts +8 -0
- package/src/providers/chart-scope/index.ts +3 -0
- package/src/providers/chart-scope/test/chart-scope.test.tsx +24 -0
- package/src/providers/chart-scope/test/use-standalone-scope-class.test.tsx +20 -0
- package/src/providers/chart-scope/use-chart-scope-element.ts +9 -0
- package/src/providers/chart-scope/use-standalone-scope-class.ts +13 -0
- package/src/providers/index.ts +1 -0
- package/src/styles/chart-scope-class.ts +6 -0
- package/src/styles/chart-scope.scss +83 -0
- package/src/styles/test/chart-scope.test.ts +165 -0
- package/src/types.ts +0 -34
- package/src/charts/private/grid-control/grid-control.module.scss +0 -8
- package/src/charts/private/grid-control/grid-control.tsx +0 -26
- package/src/charts/private/grid-control/index.ts +0 -1
- package/src/charts/private/grid-control/test/grid-control.test.tsx +0 -56
package/dist/index.cjs
CHANGED
|
@@ -64,6 +64,14 @@ const useChartInstanceContext = () => {
|
|
|
64
64
|
};
|
|
65
65
|
const useSingleChartContext = useChartInstanceContext;
|
|
66
66
|
//#endregion
|
|
67
|
+
//#region src/styles/chart-scope-class.ts
|
|
68
|
+
/**
|
|
69
|
+
* Stable class that carries the `--a8c-charts-*` catalog. Applied to the `GlobalChartsProvider` wrapper, to portal-rendered surfaces (which sit outside the provider tree), and to standalone components when no provider is above them.
|
|
70
|
+
*
|
|
71
|
+
* Deliberately unhashed: consumers are documented as being able to target it to override a token on the provider element.
|
|
72
|
+
*/
|
|
73
|
+
const CHART_SCOPE_CLASS = "a8c-charts-scope";
|
|
74
|
+
//#endregion
|
|
67
75
|
//#region src/utils/create-composition.ts
|
|
68
76
|
/**
|
|
69
77
|
* Utility function to create chart components with composition API.
|
|
@@ -620,6 +628,14 @@ const resolveFontSize = (val) => {
|
|
|
620
628
|
}
|
|
621
629
|
};
|
|
622
630
|
//#endregion
|
|
631
|
+
//#region src/providers/chart-scope/chart-scope-context.ts
|
|
632
|
+
/**
|
|
633
|
+
* The nearest chart element, published so JS token resolution reads the same CSS cascade that paints the chart's own colours.
|
|
634
|
+
*
|
|
635
|
+
* All JS token resolution reads this element rather than `document.documentElement`, so a `getComputedStyle` call sees the same `--a8c-charts-*` values — including any override set inside the provider tree — that a CSS-painted sibling element does.
|
|
636
|
+
*/
|
|
637
|
+
const ChartScopeContext = (0, react.createContext)(null);
|
|
638
|
+
//#endregion
|
|
623
639
|
//#region src/providers/chart-context/private/get-chart-color.ts
|
|
624
640
|
/**
|
|
625
641
|
* Golden ratio for mathematically pleasing color distribution
|
|
@@ -749,12 +765,75 @@ const getChartColor = (index, colorCache) => {
|
|
|
749
765
|
return (0, _visx_vendor_d3_color.hsl)(Math.round(fallbackHue), fallbackSaturation / 100, fallbackLightness / 100).formatHex();
|
|
750
766
|
};
|
|
751
767
|
//#endregion
|
|
768
|
+
//#region src/providers/chart-context/private/theme-override-vars.ts
|
|
769
|
+
const ROLE_FOR_FIELD = [
|
|
770
|
+
["--a8c-charts-color-background", (theme) => theme.backgroundColor],
|
|
771
|
+
["--a8c-charts-color-grid", (theme) => theme.gridStyles?.stroke],
|
|
772
|
+
["--a8c-charts-color-axis", (theme) => theme.xAxisLineStyles?.stroke],
|
|
773
|
+
["--a8c-charts-color-tick", (theme) => theme.xTickLineStyles?.stroke],
|
|
774
|
+
["--a8c-charts-color-label-axis", (theme) => theme.svgLabelSmall?.fill]
|
|
775
|
+
];
|
|
776
|
+
/**
|
|
777
|
+
* The variable a `theme` prop override is published as, one layer outside the role itself.
|
|
778
|
+
*
|
|
779
|
+
* `chart-scope.scss` declares each of these roles as `var(<role>-theme, <catalog default>)`, so an override that is invalid at computed-value time — a fallback-less `var()` naming a token the host never set — only invalidates this variable, and the role still resolves its mapped `--wpds-*` token. Published as the role directly, such a value took the role and every bare `var(<role>)` read site down with it.
|
|
780
|
+
*
|
|
781
|
+
* @param role - The catalog role being overridden.
|
|
782
|
+
* @return The custom property carrying the consumer's value.
|
|
783
|
+
*/
|
|
784
|
+
const themeLayerVar = (role) => `${role}-theme`;
|
|
785
|
+
ROLE_FOR_FIELD.map(([role]) => role);
|
|
786
|
+
/**
|
|
787
|
+
* Whether a value reads the role it is being published for, which would make the catalog entry depend on itself.
|
|
788
|
+
*
|
|
789
|
+
* The dependency runs `<role>: var(<role>-theme, …)`, so a value naming `<role>` closes a cycle through the catalog entry. CSS marks every custom property in a cycle invalid at computed-value time — the role's own fallback is *not* used, so the token resolves to nothing and every chart loses that colour. Verified in Chrome: `--role-theme: var(--role, blue); --role: var(--role-theme, green)` leaves `--role` empty, not `green`.
|
|
790
|
+
*
|
|
791
|
+
* Three things this has to get right, none of which a plain substring test gets:
|
|
792
|
+
*
|
|
793
|
+
* `var()` permits whitespace after the opening paren, so testing for `var(<role>` misses `var( --a8c-charts-color-grid, … )`.
|
|
794
|
+
*
|
|
795
|
+
* Several roles are prefixes of others (`--a8c-charts-color-label` of `--a8c-charts-color-label-secondary`), and every role is a prefix of its own theme layer. A prefix match would read a legitimate cross-role pointer as a self-reference and silently drop the override, so the role must be followed by something that cannot continue an identifier — `-` included. A value naming `<role>-theme` is therefore not treated as a self-reference: that cycle is confined to the theme layer, which leaves the role free to fall back to the catalog default.
|
|
796
|
+
*
|
|
797
|
+
* `resolveCssVariable` also accepts a bare custom-property name with no `var()` wrapper (`--a8c-charts-color-grid`), so that is legal `theme` input too. It forms no cycle — custom properties accept arbitrary token streams — so it survives as a literal string and drops silently at the use site instead of falling back to the catalog default.
|
|
798
|
+
*
|
|
799
|
+
* @param value - The consumer's value for the field.
|
|
800
|
+
* @param role - The catalog role this value would override.
|
|
801
|
+
* @return True when the value reads `role`, so it must not be published.
|
|
802
|
+
*/
|
|
803
|
+
const readsOwnRole = (value, role) => value.trim() === role || new RegExp(`var\\(\\s*${role.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?![\\w-])`).test(value);
|
|
804
|
+
/**
|
|
805
|
+
* Maps a sparse consumer theme onto the theme-layer variables its overridden catalog roles read, so CSS-painted and JS-resolved colours read one source.
|
|
806
|
+
*
|
|
807
|
+
* A value that reads the role it would override is left unpublished — that is the default theme's own pointer surviving `mergeThemes`, and publishing it would invalidate the role. The role is still reported in `roles`: `withCatalogPointers` restores its theme field to the catalog pointer either way, so CSS and visx agree on the catalog default rather than visx painting a literal CSS never sees.
|
|
808
|
+
*
|
|
809
|
+
* @param theme - The consumer's `theme` prop, before merging with the default theme.
|
|
810
|
+
* @return The wrapper's custom properties, and the roles the consumer overrode.
|
|
811
|
+
*/
|
|
812
|
+
const themeOverrideVars = (theme) => {
|
|
813
|
+
if (!theme) return {
|
|
814
|
+
vars: {},
|
|
815
|
+
roles: []
|
|
816
|
+
};
|
|
817
|
+
const vars = {};
|
|
818
|
+
const roles = [];
|
|
819
|
+
for (const [role, read] of ROLE_FOR_FIELD) {
|
|
820
|
+
const value = read(theme);
|
|
821
|
+
if (typeof value !== "string" || value === "") continue;
|
|
822
|
+
roles.push(role);
|
|
823
|
+
if (!readsOwnRole(value, role)) vars[themeLayerVar(role)] = value;
|
|
824
|
+
}
|
|
825
|
+
return {
|
|
826
|
+
vars,
|
|
827
|
+
roles
|
|
828
|
+
};
|
|
829
|
+
};
|
|
830
|
+
//#endregion
|
|
752
831
|
//#region src/providers/chart-context/themes.ts
|
|
753
832
|
/**
|
|
754
833
|
* Default theme configuration
|
|
755
834
|
*/
|
|
756
835
|
const defaultTheme = {
|
|
757
|
-
backgroundColor: "var(--a8c-charts-color-background,
|
|
836
|
+
backgroundColor: "var(--a8c-charts-color-background, #fff)",
|
|
758
837
|
labelBackgroundColor: "transparent",
|
|
759
838
|
labelTextColor: "var(--a8c-charts-color-label-on-fill, #FFFFFF)",
|
|
760
839
|
colors: [
|
|
@@ -765,59 +844,59 @@ const defaultTheme = {
|
|
|
765
844
|
"#FF8C8F"
|
|
766
845
|
],
|
|
767
846
|
gridStyles: {
|
|
768
|
-
stroke: "var(--a8c-charts-color-grid,
|
|
847
|
+
stroke: "var(--a8c-charts-color-grid, #dbdbdb)",
|
|
769
848
|
strokeWidth: 1
|
|
770
849
|
},
|
|
771
850
|
tickLength: 4,
|
|
772
851
|
gridColor: "",
|
|
773
852
|
gridColorDark: "",
|
|
774
853
|
xTickLineStyles: {
|
|
775
|
-
stroke: "var(--a8c-charts-color-tick,
|
|
854
|
+
stroke: "var(--a8c-charts-color-tick, #dbdbdb)",
|
|
776
855
|
strokeWidth: 1
|
|
777
856
|
},
|
|
778
857
|
xAxisLineStyles: {
|
|
779
|
-
stroke: "var(--a8c-charts-color-axis,
|
|
858
|
+
stroke: "var(--a8c-charts-color-axis, #dbdbdb)",
|
|
780
859
|
strokeWidth: 1
|
|
781
860
|
},
|
|
782
861
|
legend: {
|
|
783
|
-
labelStyles: { color: "var(--a8c-charts-color-label,
|
|
862
|
+
labelStyles: { color: "var(--a8c-charts-color-label, #1e1e1e)" },
|
|
784
863
|
containerStyles: {},
|
|
785
864
|
shapeStyles: []
|
|
786
865
|
},
|
|
787
866
|
seriesLineStyles: [],
|
|
788
867
|
glyphs: [],
|
|
789
868
|
svgLabelSmall: {
|
|
790
|
-
fill: "var(--a8c-charts-color-label
|
|
869
|
+
fill: "var(--a8c-charts-color-label-axis, #1e1e1e)",
|
|
791
870
|
fontFamily: "inherit"
|
|
792
871
|
},
|
|
793
872
|
svgLabelBig: { fontFamily: "inherit" },
|
|
794
873
|
annotationStyles: {
|
|
795
874
|
label: {
|
|
796
|
-
anchorLineStroke: "var(--a8c-charts-color-annotation,
|
|
797
|
-
backgroundFill: "var(--a8c-charts-color-
|
|
875
|
+
anchorLineStroke: "var(--a8c-charts-color-annotation, #1e1e1e)",
|
|
876
|
+
backgroundFill: "var(--a8c-charts-color-surface, #fff)"
|
|
798
877
|
},
|
|
799
|
-
connector: { stroke: "var(--a8c-charts-color-annotation,
|
|
878
|
+
connector: { stroke: "var(--a8c-charts-color-annotation, #1e1e1e)" },
|
|
800
879
|
circleSubject: {
|
|
801
880
|
stroke: "transparent",
|
|
802
|
-
fill: "var(--a8c-charts-color-annotation,
|
|
881
|
+
fill: "var(--a8c-charts-color-annotation, #1e1e1e)",
|
|
803
882
|
radius: 5
|
|
804
883
|
}
|
|
805
884
|
},
|
|
806
|
-
geoChart: { featureFillColor: "var(--a8c-charts-color-surface-secondary,
|
|
885
|
+
geoChart: { featureFillColor: "var(--a8c-charts-color-surface-secondary, #f4f4f4)" },
|
|
807
886
|
leaderboardChart: {
|
|
808
887
|
rowGap: 12,
|
|
809
888
|
columnGap: 4,
|
|
810
889
|
labelSpacing: "xs",
|
|
811
890
|
deltaColors: [
|
|
812
|
-
"var(--a8c-charts-color-trend-down,
|
|
813
|
-
"var(--a8c-charts-color-trend-neutral,
|
|
814
|
-
"var(--a8c-charts-color-trend-up,
|
|
891
|
+
"var(--a8c-charts-color-trend-down, #cc1818)",
|
|
892
|
+
"var(--a8c-charts-color-trend-neutral, #707070)",
|
|
893
|
+
"var(--a8c-charts-color-trend-up, #008030)"
|
|
815
894
|
]
|
|
816
895
|
},
|
|
817
896
|
conversionFunnelChart: {
|
|
818
|
-
backgroundColor: "var(--a8c-charts-color-surface-secondary,
|
|
819
|
-
positiveChangeColor: "var(--a8c-charts-color-trend-up,
|
|
820
|
-
negativeChangeColor: "var(--a8c-charts-color-trend-down,
|
|
897
|
+
backgroundColor: "var(--a8c-charts-color-surface-secondary, #f4f4f4)",
|
|
898
|
+
positiveChangeColor: "var(--a8c-charts-color-trend-up, #008030)",
|
|
899
|
+
negativeChangeColor: "var(--a8c-charts-color-trend-down, #cc1818)"
|
|
821
900
|
},
|
|
822
901
|
lineChart: { lineStyles: { comparison: {
|
|
823
902
|
strokeDasharray: "4 4",
|
|
@@ -842,15 +921,65 @@ const defaultTheme = {
|
|
|
842
921
|
}
|
|
843
922
|
};
|
|
844
923
|
//#endregion
|
|
924
|
+
//#region src/providers/chart-context/private/with-catalog-pointers.ts
|
|
925
|
+
const CATALOG_RESTORE_FOR_ROLE = {
|
|
926
|
+
"--a8c-charts-color-background": () => ({ backgroundColor: defaultTheme.backgroundColor }),
|
|
927
|
+
"--a8c-charts-color-grid": (theme) => ({ gridStyles: {
|
|
928
|
+
...theme.gridStyles,
|
|
929
|
+
stroke: defaultTheme.gridStyles.stroke
|
|
930
|
+
} }),
|
|
931
|
+
"--a8c-charts-color-axis": (theme) => ({ xAxisLineStyles: {
|
|
932
|
+
...theme.xAxisLineStyles,
|
|
933
|
+
stroke: defaultTheme.xAxisLineStyles.stroke
|
|
934
|
+
} }),
|
|
935
|
+
"--a8c-charts-color-tick": (theme) => ({ xTickLineStyles: {
|
|
936
|
+
...theme.xTickLineStyles,
|
|
937
|
+
stroke: defaultTheme.xTickLineStyles.stroke
|
|
938
|
+
} }),
|
|
939
|
+
"--a8c-charts-color-label-axis": (theme) => ({ svgLabelSmall: {
|
|
940
|
+
...theme.svgLabelSmall,
|
|
941
|
+
fill: defaultTheme.svgLabelSmall.fill
|
|
942
|
+
} })
|
|
943
|
+
};
|
|
944
|
+
/**
|
|
945
|
+
* Restores the mapped theme fields of `overriddenRoles` to their catalog pointer, so the theme-layer variable `themeOverrideVars` writes on the provider wrapper is the only carrier for an overridden role — CSS and the JS bridge (`useXYChartTheme`) then resolve it through the same cascade instead of visx reading a baked literal that can disagree with a closer CSS override.
|
|
946
|
+
*
|
|
947
|
+
* This covers roles `themeOverrideVars` deliberately left unpublished as well as the ones it published. A value that reads its own role is not publishable, but leaving visx the consumer's literal is what the whole mechanism exists to prevent: `theme={ { gridStyles: { stroke: 'var(--brand, var(--a8c-charts-color-grid, red))' } } }` would have CSS paint the catalog default while visx painted `--brand`.
|
|
948
|
+
*
|
|
949
|
+
* Every field outside the five mapped roles is left exactly as `merged` provided it: those aren't published as theme-layer vars, so rewriting them would erase a consumer's override with no replacement carrier.
|
|
950
|
+
*
|
|
951
|
+
* @param merged - The consumer theme merged onto `defaultTheme` (`mergeThemes` output).
|
|
952
|
+
* @param overriddenRoles - The catalog roles the consumer overrode, from `themeOverrideVars`.
|
|
953
|
+
* @return A new theme object; `merged` is not mutated.
|
|
954
|
+
*/
|
|
955
|
+
const withCatalogPointers = (merged, overriddenRoles) => {
|
|
956
|
+
let result = merged;
|
|
957
|
+
for (const role of overriddenRoles) {
|
|
958
|
+
const restore = CATALOG_RESTORE_FOR_ROLE[role];
|
|
959
|
+
if (restore) result = {
|
|
960
|
+
...result,
|
|
961
|
+
...restore(result)
|
|
962
|
+
};
|
|
963
|
+
}
|
|
964
|
+
return result;
|
|
965
|
+
};
|
|
966
|
+
//#endregion
|
|
845
967
|
//#region src/providers/chart-context/global-charts-provider.tsx
|
|
846
968
|
const GlobalChartsContext = (0, react.createContext)(null);
|
|
847
969
|
const GlobalChartsProvider = ({ children, theme }) => {
|
|
848
970
|
const [charts, setCharts] = (0, react.useState)(() => /* @__PURE__ */ new Map());
|
|
849
971
|
const [hiddenSeries, setHiddenSeries] = (0, react.useState)(() => /* @__PURE__ */ new Map());
|
|
850
972
|
const wrapperRef = (0, react.useRef)(null);
|
|
973
|
+
const [scopeNode, setScopeNode] = (0, react.useState)(null);
|
|
974
|
+
const setWrapperNode = (0, react.useCallback)((node) => {
|
|
975
|
+
wrapperRef.current = node;
|
|
976
|
+
setScopeNode(node);
|
|
977
|
+
}, []);
|
|
978
|
+
const { vars: overrideVars, roles: overriddenRoles } = (0, react.useMemo)(() => themeOverrideVars(theme), [theme]);
|
|
851
979
|
const providerTheme = (0, react.useMemo)(() => {
|
|
852
|
-
|
|
853
|
-
|
|
980
|
+
if (!theme) return defaultTheme;
|
|
981
|
+
return withCatalogPointers(mergeThemes(defaultTheme, theme), overriddenRoles);
|
|
982
|
+
}, [theme, overriddenRoles]);
|
|
854
983
|
const [colorCache, setColorCache] = (0, react.useState)(() => ({
|
|
855
984
|
colors: [],
|
|
856
985
|
hues: [],
|
|
@@ -927,7 +1056,6 @@ const GlobalChartsProvider = ({ children, theme }) => {
|
|
|
927
1056
|
}
|
|
928
1057
|
return getChartColor(index, colorCache);
|
|
929
1058
|
}, [colorCache, groupToColorMap]);
|
|
930
|
-
const resolveThemeColor = (0, react.useCallback)((value) => value ? normalizeColorToHex(value, wrapperRef.current, resolveCssVariable) : "", []);
|
|
931
1059
|
const getElementStyles = (0, react.useCallback)(({ data, index, overrideColor, legendShape }) => {
|
|
932
1060
|
const isSeriesData = data && typeof data === "object" && "data" in data && "options" in data;
|
|
933
1061
|
const isPointPercentageData = data && typeof data === "object" && "value" in data && typeof data.value === "number" && !("data" in data);
|
|
@@ -970,7 +1098,6 @@ const GlobalChartsProvider = ({ children, theme }) => {
|
|
|
970
1098
|
getChartData,
|
|
971
1099
|
theme: providerTheme,
|
|
972
1100
|
getElementStyles,
|
|
973
|
-
resolveThemeColor,
|
|
974
1101
|
toggleSeriesVisibility,
|
|
975
1102
|
isSeriesVisible,
|
|
976
1103
|
getHiddenSeries,
|
|
@@ -982,7 +1109,6 @@ const GlobalChartsProvider = ({ children, theme }) => {
|
|
|
982
1109
|
getChartData,
|
|
983
1110
|
providerTheme,
|
|
984
1111
|
getElementStyles,
|
|
985
|
-
resolveThemeColor,
|
|
986
1112
|
toggleSeriesVisibility,
|
|
987
1113
|
isSeriesVisible,
|
|
988
1114
|
getHiddenSeries,
|
|
@@ -991,9 +1117,16 @@ const GlobalChartsProvider = ({ children, theme }) => {
|
|
|
991
1117
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GlobalChartsContext.Provider, {
|
|
992
1118
|
value,
|
|
993
1119
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
994
|
-
ref:
|
|
995
|
-
|
|
996
|
-
|
|
1120
|
+
ref: setWrapperNode,
|
|
1121
|
+
className: CHART_SCOPE_CLASS,
|
|
1122
|
+
style: {
|
|
1123
|
+
display: "contents",
|
|
1124
|
+
...overrideVars
|
|
1125
|
+
},
|
|
1126
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChartScopeContext.Provider, {
|
|
1127
|
+
value: scopeNode,
|
|
1128
|
+
children
|
|
1129
|
+
})
|
|
997
1130
|
})
|
|
998
1131
|
});
|
|
999
1132
|
};
|
|
@@ -1053,12 +1186,31 @@ const useDeepMemo = (value) => {
|
|
|
1053
1186
|
return ref.current;
|
|
1054
1187
|
};
|
|
1055
1188
|
//#endregion
|
|
1189
|
+
//#region src/providers/chart-scope/use-chart-scope-element.ts
|
|
1190
|
+
/**
|
|
1191
|
+
* Returns the nearest chart scope element, or `null` when rendered outside any scope (and during SSR, before the ref is attached).
|
|
1192
|
+
*
|
|
1193
|
+
* @return {HTMLElement | null} The nearest chart scope element, or `null`.
|
|
1194
|
+
*/
|
|
1195
|
+
const useChartScopeElement = () => (0, react.useContext)(ChartScopeContext);
|
|
1196
|
+
//#endregion
|
|
1197
|
+
//#region src/providers/chart-scope/use-standalone-scope-class.ts
|
|
1198
|
+
/**
|
|
1199
|
+
* Returns the catalog class when there is no `GlobalChartsProvider` above this component, and `undefined` when there is.
|
|
1200
|
+
*
|
|
1201
|
+
* Standalone components need the catalog to resolve at all, but inside a provider the tokens already inherit — re-declaring them there would shadow a consumer override set anywhere in the tree.
|
|
1202
|
+
*
|
|
1203
|
+
* @return The scope class name, or undefined when a provider is present.
|
|
1204
|
+
*/
|
|
1205
|
+
const useStandaloneScopeClass = () => (0, react.useContext)(GlobalChartsContext) ? void 0 : CHART_SCOPE_CLASS;
|
|
1206
|
+
//#endregion
|
|
1056
1207
|
//#region src/hooks/use-xychart-theme.ts
|
|
1057
1208
|
const useXYChartTheme = (data) => {
|
|
1058
1209
|
const theme = useGlobalChartsTheme();
|
|
1210
|
+
const scopeElement = useChartScopeElement();
|
|
1059
1211
|
const seriesColorKey = JSON.stringify((data ?? []).map((series) => series.options?.stroke).filter((color) => Boolean(color)));
|
|
1060
1212
|
return (0, react.useMemo)(() => {
|
|
1061
|
-
const resolve = createCssVariableResolver();
|
|
1213
|
+
const resolve = createCssVariableResolver(scopeElement);
|
|
1062
1214
|
const resolveColor = (value) => value ? resolve(value) ?? value : value;
|
|
1063
1215
|
const seriesColors = JSON.parse(seriesColorKey);
|
|
1064
1216
|
return (0, _visx_xychart.buildChartTheme)({
|
|
@@ -1082,7 +1234,11 @@ const useXYChartTheme = (data) => {
|
|
|
1082
1234
|
fill: resolveColor(theme.svgLabelSmall.fill)
|
|
1083
1235
|
}
|
|
1084
1236
|
});
|
|
1085
|
-
}, [
|
|
1237
|
+
}, [
|
|
1238
|
+
theme,
|
|
1239
|
+
seriesColorKey,
|
|
1240
|
+
scopeElement
|
|
1241
|
+
]);
|
|
1086
1242
|
};
|
|
1087
1243
|
//#endregion
|
|
1088
1244
|
//#region src/hooks/use-chart-data-transform.ts
|
|
@@ -1558,6 +1714,7 @@ const BaseLegend = (0, react.forwardRef)(({ items, className, orientation = "hor
|
|
|
1558
1714
|
const { width: shapeWidth = 16, height: shapeHeight = 16, margin: shapeMargin = "2px 4px 2px 0" } = shapeStyles ?? {};
|
|
1559
1715
|
const theme = useGlobalChartsTheme();
|
|
1560
1716
|
const context = (0, react.useContext)(GlobalChartsContext);
|
|
1717
|
+
const standaloneScopeClass = useStandaloneScopeClass();
|
|
1561
1718
|
const legendScale = (0, _visx_scale.scaleOrdinal)({
|
|
1562
1719
|
domain: items.map((item) => item.label),
|
|
1563
1720
|
range: items.map((item) => item.color)
|
|
@@ -1610,7 +1767,7 @@ const BaseLegend = (0, react.forwardRef)(({ items, className, orientation = "hor
|
|
|
1610
1767
|
justify: orientation === "horizontal" ? flexAlignment : void 0,
|
|
1611
1768
|
wrap: orientation === "horizontal" ? "wrap" : void 0,
|
|
1612
1769
|
role: "list",
|
|
1613
|
-
className: (0, clsx.default)(base_legend_module_default.legend, className),
|
|
1770
|
+
className: (0, clsx.default)(standaloneScopeClass, base_legend_module_default.legend, className),
|
|
1614
1771
|
style: theme.legend?.containerStyles,
|
|
1615
1772
|
children: labels.map((label, i) => {
|
|
1616
1773
|
const matchedItem = items[i];
|
|
@@ -1897,9 +2054,10 @@ const BaseTooltip = ({ data, top, left, component: Component = DefaultTooltipCon
|
|
|
1897
2054
|
data,
|
|
1898
2055
|
className
|
|
1899
2056
|
});
|
|
2057
|
+
const standaloneScopeClass = useStandaloneScopeClass();
|
|
1900
2058
|
if (!renderContainer) return content;
|
|
1901
2059
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1902
|
-
className: base_tooltip_module_default.tooltip,
|
|
2060
|
+
className: (0, clsx.default)(standaloneScopeClass, base_tooltip_module_default.tooltip),
|
|
1903
2061
|
style: {
|
|
1904
2062
|
top,
|
|
1905
2063
|
left,
|
|
@@ -1968,10 +2126,11 @@ const AccessibleTooltip = ({ renderTooltip, selectedIndex, tooltipRef, keyboardF
|
|
|
1968
2126
|
tabIndex: -1,
|
|
1969
2127
|
role: "tooltip",
|
|
1970
2128
|
"aria-atomic": "true",
|
|
1971
|
-
className: keyboardFocusedClassName,
|
|
2129
|
+
className: (0, clsx.default)(CHART_SCOPE_CLASS, keyboardFocusedClassName),
|
|
1972
2130
|
children: tooltipContent
|
|
1973
2131
|
}, `chart-tooltip-${selectedIndex}`);
|
|
1974
2132
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2133
|
+
className: CHART_SCOPE_CLASS,
|
|
1975
2134
|
role: "tooltip",
|
|
1976
2135
|
"aria-live": "polite",
|
|
1977
2136
|
children: tooltipContent
|
|
@@ -2424,9 +2583,11 @@ function withResponsive(WrappedComponent) {
|
|
|
2424
2583
|
enableDebounceLeadingCall: true
|
|
2425
2584
|
});
|
|
2426
2585
|
const hasAspectRatio = aspectRatio !== void 0 && aspectRatio > 0;
|
|
2586
|
+
const [scopeNode, setScopeNode] = (0, react.useState)(null);
|
|
2427
2587
|
const wrapperRef = (0, react.useRef)(null);
|
|
2428
2588
|
const setWrapperRef = (0, react.useCallback)((node) => {
|
|
2429
2589
|
wrapperRef.current = node;
|
|
2590
|
+
setScopeNode(node);
|
|
2430
2591
|
if (typeof parentRef === "function") parentRef(node);
|
|
2431
2592
|
else if (parentRef) parentRef.current = node;
|
|
2432
2593
|
}, [parentRef]);
|
|
@@ -2472,14 +2633,17 @@ function withResponsive(WrappedComponent) {
|
|
|
2472
2633
|
...width !== void 0 ? { width } : null,
|
|
2473
2634
|
...height !== void 0 ? { height } : null
|
|
2474
2635
|
},
|
|
2475
|
-
children:
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2636
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChartScopeContext.Provider, {
|
|
2637
|
+
value: scopeNode,
|
|
2638
|
+
children: hasAspectRatio ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2639
|
+
className: with_responsive_module_default.content,
|
|
2640
|
+
style: {
|
|
2641
|
+
width: boxWidth,
|
|
2642
|
+
height: boxHeight
|
|
2643
|
+
},
|
|
2644
|
+
children: wrappedComponent
|
|
2645
|
+
}) : wrappedComponent
|
|
2646
|
+
})
|
|
2483
2647
|
});
|
|
2484
2648
|
};
|
|
2485
2649
|
}
|
|
@@ -2914,11 +3078,12 @@ const getVerticalAnchor = (subjectType, isFlippedVertically, y, yMax, height) =>
|
|
|
2914
3078
|
};
|
|
2915
3079
|
const LineChartAnnotation = ({ datum, title, subtitle, subjectType = "circle", styles: datumStyles, testId, renderLabel, renderLabelPopover }) => {
|
|
2916
3080
|
const providerTheme = useGlobalChartsTheme();
|
|
3081
|
+
const scopeElement = useChartScopeElement();
|
|
2917
3082
|
const { xScale, yScale } = (0, react.useContext)(_visx_xychart.DataContext) || {};
|
|
2918
3083
|
const labelRef = (0, react.useRef)(null);
|
|
2919
3084
|
const [height, setHeight] = (0, react.useState)(null);
|
|
2920
3085
|
const styles = (0, deepmerge.default)(providerTheme.annotationStyles ?? {}, datumStyles ?? {});
|
|
2921
|
-
const resolveColor = (value) => value ? resolveCssVariable(value) ?? value : value;
|
|
3086
|
+
const resolveColor = (value) => value ? resolveCssVariable(value, scopeElement) ?? value : value;
|
|
2922
3087
|
(0, react.useEffect)(() => {
|
|
2923
3088
|
if (labelRef.current?.getBBox) {
|
|
2924
3089
|
const bbox = labelRef.current.getBBox();
|
|
@@ -5069,12 +5234,22 @@ const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loadi
|
|
|
5069
5234
|
const { getElementStyles, isColorPaletteResolved } = useGlobalChartsContext();
|
|
5070
5235
|
const chartRef = (0, react.useRef)(null);
|
|
5071
5236
|
const selectedBarRef = (0, react.useRef)(null);
|
|
5237
|
+
const [scopeNode, setScopeNode] = (0, react.useState)(null);
|
|
5072
5238
|
const { tooltipData, tooltipLeft, tooltipTop, tooltipOpen, showTooltip, hideTooltip } = (0, _visx_tooltip.useTooltip)();
|
|
5073
5239
|
const { handleBarClick, handleBarKeyDown, clearSelection, getStepState } = useFunnelSelection(hideTooltip);
|
|
5074
5240
|
const { containerRef: portalContainerRef, TooltipInPortal, containerBounds } = (0, _visx_tooltip.useTooltipInPortal)({
|
|
5075
5241
|
detectBounds: true,
|
|
5076
5242
|
scroll: true
|
|
5077
5243
|
});
|
|
5244
|
+
const portalContainerRefRef = (0, react.useRef)(portalContainerRef);
|
|
5245
|
+
(0, react.useEffect)(() => {
|
|
5246
|
+
portalContainerRefRef.current = portalContainerRef;
|
|
5247
|
+
}, [portalContainerRef]);
|
|
5248
|
+
const setChartRef = (0, react.useCallback)((node) => {
|
|
5249
|
+
portalContainerRefRef.current(node);
|
|
5250
|
+
chartRef.current = node;
|
|
5251
|
+
setScopeNode(node);
|
|
5252
|
+
}, []);
|
|
5078
5253
|
const clearSelectionAndRef = (0, react.useCallback)(() => {
|
|
5079
5254
|
clearSelection();
|
|
5080
5255
|
selectedBarRef.current = null;
|
|
@@ -5220,6 +5395,7 @@ const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loadi
|
|
|
5220
5395
|
direction: "column",
|
|
5221
5396
|
align: "center",
|
|
5222
5397
|
justify: "center",
|
|
5398
|
+
ref: setScopeNode,
|
|
5223
5399
|
className: (0, clsx.default)(conversion_funnel_chart_module_default["conversion-funnel-chart"], loading && conversion_funnel_chart_module_default["conversion-funnel-chart--loading"], className),
|
|
5224
5400
|
style: {
|
|
5225
5401
|
...style,
|
|
@@ -5231,80 +5407,80 @@ const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loadi
|
|
|
5231
5407
|
})
|
|
5232
5408
|
});
|
|
5233
5409
|
const maxRate = Math.max(...steps.map((step) => step.rate));
|
|
5234
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.
|
|
5410
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_wordpress_ui.Stack, {
|
|
5235
5411
|
direction: "column",
|
|
5236
5412
|
gap: "xl",
|
|
5237
|
-
ref:
|
|
5238
|
-
portalContainerRef(node);
|
|
5239
|
-
chartRef.current = node;
|
|
5240
|
-
},
|
|
5413
|
+
ref: setChartRef,
|
|
5241
5414
|
className: (0, clsx.default)(conversion_funnel_chart_module_default["conversion-funnel-chart"], loading && conversion_funnel_chart_module_default["conversion-funnel-chart--loading"], className),
|
|
5242
5415
|
style: {
|
|
5243
5416
|
...style,
|
|
5244
5417
|
height: resolvedHeight
|
|
5245
5418
|
},
|
|
5246
|
-
children:
|
|
5247
|
-
|
|
5248
|
-
|
|
5249
|
-
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
|
|
5261
|
-
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5265
|
-
|
|
5266
|
-
|
|
5267
|
-
|
|
5268
|
-
gap: "xl",
|
|
5269
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_wordpress_ui.Stack, {
|
|
5419
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(ChartScopeContext.Provider, {
|
|
5420
|
+
value: scopeNode,
|
|
5421
|
+
children: [renderMainMetric ? renderMainMetric({
|
|
5422
|
+
mainRate,
|
|
5423
|
+
changeIndicator,
|
|
5424
|
+
className: conversion_funnel_chart_module_default["main-metric"],
|
|
5425
|
+
changeColor
|
|
5426
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_wordpress_ui.Stack, {
|
|
5427
|
+
direction: "row",
|
|
5428
|
+
align: "baseline",
|
|
5429
|
+
gap: "sm",
|
|
5430
|
+
className: conversion_funnel_chart_module_default["main-metric"],
|
|
5431
|
+
children: renderDefaultMainMetric()
|
|
5432
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_wordpress_ui.Stack, {
|
|
5433
|
+
direction: "row",
|
|
5434
|
+
align: "flex-end",
|
|
5435
|
+
gap: "lg",
|
|
5436
|
+
className: conversion_funnel_chart_module_default["funnel-container"],
|
|
5437
|
+
children: steps.map((step, index) => {
|
|
5438
|
+
const barHeight = step.rate / maxRate * 100;
|
|
5439
|
+
const { isBlurred } = getStepState(step.id);
|
|
5440
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_wordpress_ui.Stack, {
|
|
5270
5441
|
direction: "column",
|
|
5271
|
-
|
|
5272
|
-
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
|
|
5279
|
-
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
|
|
5285
|
-
|
|
5442
|
+
className: (0, clsx.default)(conversion_funnel_chart_module_default["funnel-step"], isColorPaletteResolved && conversion_funnel_chart_module_default["funnel-step--animated"], isBlurred && conversion_funnel_chart_module_default["funnel-step--blurred"]),
|
|
5443
|
+
gap: "xl",
|
|
5444
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_wordpress_ui.Stack, {
|
|
5445
|
+
direction: "column",
|
|
5446
|
+
gap: "xs",
|
|
5447
|
+
children: [renderStepLabel ? renderStepLabel({
|
|
5448
|
+
step,
|
|
5449
|
+
index,
|
|
5450
|
+
className: conversion_funnel_chart_module_default["step-label"]
|
|
5451
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5452
|
+
className: conversion_funnel_chart_module_default["step-label"],
|
|
5453
|
+
children: step.label
|
|
5454
|
+
}), renderStepRate ? renderStepRate({
|
|
5455
|
+
step,
|
|
5456
|
+
index,
|
|
5457
|
+
className: conversion_funnel_chart_module_default["step-rate"]
|
|
5458
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5459
|
+
className: conversion_funnel_chart_module_default["step-rate"],
|
|
5460
|
+
children: formatPercentage(step.rate)
|
|
5461
|
+
})]
|
|
5462
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_wordpress_ui.Stack, {
|
|
5463
|
+
direction: "column",
|
|
5464
|
+
justify: "flex-end",
|
|
5465
|
+
className: conversion_funnel_chart_module_default["bar-container"],
|
|
5466
|
+
onClick: stepHandlers.get(step.id)?.onClick,
|
|
5467
|
+
onKeyDown: stepHandlers.get(step.id)?.onKeyDown,
|
|
5468
|
+
role: "button",
|
|
5469
|
+
tabIndex: isBlurred ? -1 : 0,
|
|
5470
|
+
"aria-label": step.label,
|
|
5471
|
+
style: { backgroundColor: barBackgroundColor },
|
|
5472
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5473
|
+
className: (0, clsx.default)(conversion_funnel_chart_module_default["funnel-bar"], { [conversion_funnel_chart_module_default["funnel-bar--animated"]]: animation && !loading && !prefersReducedMotion }),
|
|
5474
|
+
style: {
|
|
5475
|
+
height: `${barHeight}%`,
|
|
5476
|
+
backgroundColor: barColor
|
|
5477
|
+
}
|
|
5478
|
+
})
|
|
5286
5479
|
})]
|
|
5287
|
-
}
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
onClick: stepHandlers.get(step.id)?.onClick,
|
|
5292
|
-
onKeyDown: stepHandlers.get(step.id)?.onKeyDown,
|
|
5293
|
-
role: "button",
|
|
5294
|
-
tabIndex: isBlurred ? -1 : 0,
|
|
5295
|
-
"aria-label": step.label,
|
|
5296
|
-
style: { backgroundColor: barBackgroundColor },
|
|
5297
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5298
|
-
className: (0, clsx.default)(conversion_funnel_chart_module_default["funnel-bar"], { [conversion_funnel_chart_module_default["funnel-bar--animated"]]: animation && !loading && !prefersReducedMotion }),
|
|
5299
|
-
style: {
|
|
5300
|
-
height: `${barHeight}%`,
|
|
5301
|
-
backgroundColor: barColor
|
|
5302
|
-
}
|
|
5303
|
-
})
|
|
5304
|
-
})]
|
|
5305
|
-
}, step.id);
|
|
5306
|
-
})
|
|
5307
|
-
})]
|
|
5480
|
+
}, step.id);
|
|
5481
|
+
})
|
|
5482
|
+
})]
|
|
5483
|
+
})
|
|
5308
5484
|
}), tooltipOpen && tooltipData && (() => {
|
|
5309
5485
|
const tooltipContent = renderTooltip ? renderTooltip({
|
|
5310
5486
|
step: tooltipData,
|
|
@@ -5317,7 +5493,7 @@ const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loadi
|
|
|
5317
5493
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TooltipInPortal, {
|
|
5318
5494
|
top: tooltipTop,
|
|
5319
5495
|
left: tooltipLeft,
|
|
5320
|
-
className: conversion_funnel_chart_module_default["tooltip-wrapper"],
|
|
5496
|
+
className: (0, clsx.default)("a8c-charts-scope", conversion_funnel_chart_module_default["tooltip-wrapper"]),
|
|
5321
5497
|
children: tooltipContent
|
|
5322
5498
|
}, Math.random());
|
|
5323
5499
|
})()] });
|
|
@@ -5467,6 +5643,7 @@ function normalizeGeoChartError(eventArgs) {
|
|
|
5467
5643
|
*/
|
|
5468
5644
|
const GeoChartInternal = ({ className, data, width, height, region = "world", resolution = "countries", onError, renderPlaceholder }) => {
|
|
5469
5645
|
const { getElementStyles, theme: { geoChart: { featureFillColor }, backgroundColor } } = useGlobalChartsContext();
|
|
5646
|
+
const scopeElement = useChartScopeElement();
|
|
5470
5647
|
const containerRef = (0, react.useRef)(null);
|
|
5471
5648
|
const reportedErrorIdsRef = (0, react.useRef)(/* @__PURE__ */ new Set());
|
|
5472
5649
|
(0, react.useEffect)(() => {
|
|
@@ -5499,8 +5676,8 @@ const GeoChartInternal = ({ className, data, width, height, region = "world", re
|
|
|
5499
5676
|
});
|
|
5500
5677
|
const fullColorHex = getElementStyles({ index: 0 }).color;
|
|
5501
5678
|
const lightColorHex = lightenHexColor(fullColorHex, .8);
|
|
5502
|
-
const backgroundColorHex = normalizeColorToHex(backgroundColor,
|
|
5503
|
-
const defaultFillColorHex = normalizeColorToHex(featureFillColor,
|
|
5679
|
+
const backgroundColorHex = normalizeColorToHex(backgroundColor, scopeElement, resolveCssVariable) || DEFAULT_BACKGROUND_COLOR;
|
|
5680
|
+
const defaultFillColorHex = normalizeColorToHex(featureFillColor, scopeElement, resolveCssVariable) || DEFAULT_FEATURE_FILL_COLOR;
|
|
5504
5681
|
const sanitizedData = (0, react.useMemo)(() => {
|
|
5505
5682
|
if (data.length === 0) return {
|
|
5506
5683
|
data,
|
|
@@ -5760,7 +5937,8 @@ const HeatmapLegend = ({ steps = 5, lessLabel, moreLabel }) => {
|
|
|
5760
5937
|
const CELL_MIX_FLOOR = .15;
|
|
5761
5938
|
const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, height = 0, className, compact = false, showValues, maxCellWidth, maxCellHeight, minCellWidth, minCellHeight, rowLabels = [], primaryColor, gap = "md", withTooltips = false, renderTooltip, children }) => {
|
|
5762
5939
|
const chartId = useChartId(providedChartId);
|
|
5763
|
-
const { getElementStyles,
|
|
5940
|
+
const { getElementStyles, theme } = useGlobalChartsContext();
|
|
5941
|
+
const scopeElement = useChartScopeElement();
|
|
5764
5942
|
const { heatmapChart: heatmapChartSettings } = theme;
|
|
5765
5943
|
const { nonLegendChildren } = useChartChildren(children, "HeatmapChart");
|
|
5766
5944
|
const [selectedIndex, setSelectedIndex] = (0, react.useState)();
|
|
@@ -5775,7 +5953,7 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
5775
5953
|
index: 0,
|
|
5776
5954
|
overrideColor: primaryColor || heatmapChartSettings.primaryColor
|
|
5777
5955
|
});
|
|
5778
|
-
const chartBackgroundHex =
|
|
5956
|
+
const chartBackgroundHex = normalizeColorToHex(theme.backgroundColor, scopeElement, resolveCssVariable);
|
|
5779
5957
|
const primaryHex = normalizeColorToHex(primaryColorHex);
|
|
5780
5958
|
const cellHasLightText = (intensity) => isValidHexColor(primaryHex) && isValidHexColor(chartBackgroundHex) && prefersLightText(mixHexColors(primaryHex, chartBackgroundHex, 1 - (CELL_MIX_FLOOR + (1 - CELL_MIX_FLOOR) * intensity)));
|
|
5781
5959
|
const extent = (0, react.useMemo)(() => getValueExtent(data), [data]);
|
|
@@ -6002,6 +6180,7 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
6002
6180
|
top: tooltipTop,
|
|
6003
6181
|
left: tooltipLeft,
|
|
6004
6182
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6183
|
+
className: "a8c-charts-scope",
|
|
6005
6184
|
role: "tooltip",
|
|
6006
6185
|
tabIndex: -1,
|
|
6007
6186
|
children: (renderTooltip ?? defaultRenderTooltip)(tooltipData)
|
|
@@ -9337,6 +9516,7 @@ const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false
|
|
|
9337
9516
|
top: tooltipTop || 0,
|
|
9338
9517
|
left: tooltipLeft || 0,
|
|
9339
9518
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9519
|
+
className: "a8c-charts-scope",
|
|
9340
9520
|
role: "tooltip",
|
|
9341
9521
|
children: renderTooltip({ tooltipData })
|
|
9342
9522
|
})
|
|
@@ -9635,6 +9815,7 @@ const PieSemiCircleChartInternal = ({ data, chartId: providedChartId, width: pro
|
|
|
9635
9815
|
top: tooltipTop || 0,
|
|
9636
9816
|
left: tooltipLeft || 0,
|
|
9637
9817
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9818
|
+
className: "a8c-charts-scope",
|
|
9638
9819
|
role: "tooltip",
|
|
9639
9820
|
children: renderTooltip({ tooltipData })
|
|
9640
9821
|
})
|
|
@@ -9922,7 +10103,7 @@ const Icon = ({ direction }) => {
|
|
|
9922
10103
|
function TrendIndicator({ direction, value, className, style, showIcon = true }) {
|
|
9923
10104
|
const ariaLabel = `${DIRECTION_LABELS[direction]}: ${value}`;
|
|
9924
10105
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
9925
|
-
className: (0, clsx.default)(trend_indicator_module_default["trend-indicator"], trend_indicator_module_default[`trend-indicator--${direction}`], className),
|
|
10106
|
+
className: (0, clsx.default)(useStandaloneScopeClass(), trend_indicator_module_default["trend-indicator"], trend_indicator_module_default[`trend-indicator--${direction}`], className),
|
|
9926
10107
|
style,
|
|
9927
10108
|
"aria-label": ariaLabel,
|
|
9928
10109
|
children: [showIcon && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { direction }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
@@ -9976,7 +10157,10 @@ exports.parseHslString = parseHslString;
|
|
|
9976
10157
|
exports.parseRgbString = parseRgbString;
|
|
9977
10158
|
exports.prefersLightText = prefersLightText;
|
|
9978
10159
|
exports.relativeLuminance = relativeLuminance;
|
|
10160
|
+
exports.resolveCssVariable = resolveCssVariable;
|
|
9979
10161
|
exports.useChartLegendItems = useChartLegendItems;
|
|
10162
|
+
exports.useChartRegistration = useChartRegistration;
|
|
10163
|
+
exports.useChartScopeElement = useChartScopeElement;
|
|
9980
10164
|
exports.useGlobalChartsContext = useGlobalChartsContext;
|
|
9981
10165
|
exports.useGlobalChartsTheme = useGlobalChartsTheme;
|
|
9982
10166
|
exports.useLeaderboardLegendItems = useLeaderboardLegendItems;
|