diff --git a/packages/x-charts/src/ChartsLabel/ChartsLabelGradient.test.tsx b/packages/x-charts/src/ChartsLabel/ChartsLabelGradient.test.tsx
index 9e5ae7a6d0491..26eba1e27e52a 100644
--- a/packages/x-charts/src/ChartsLabel/ChartsLabelGradient.test.tsx
+++ b/packages/x-charts/src/ChartsLabel/ChartsLabelGradient.test.tsx
@@ -4,11 +4,14 @@ import { describeConformance } from 'test/utils/describeConformance';
import { createTheme, ThemeProvider } from '@mui/material/styles';
import { ChartsLabelGradient } from '@mui/x-charts/ChartsLabel/ChartsLabelGradient';
import { labelGradientClasses } from '@mui/x-charts/ChartsLabel';
+import { expect } from 'chai';
+import { describeSkipIf, isJSDOM } from 'test/utils/skipIf';
+import RtlProvider from '@mui/system/RtlProvider';
describe('', () => {
const { render } = createRenderer();
- describeConformance(, () => ({
+ describeConformance(, () => ({
classes: labelGradientClasses,
inheritComponent: 'div',
render: (node) =>
@@ -16,7 +19,7 @@ describe('', () => {
wrapper: ({ children }) => (
{children}
-
+
),
}),
@@ -28,6 +31,163 @@ describe('', () => {
// SKIP
skip: ['themeVariants', 'componentProp', 'componentsProp'],
}));
+
+ // JSDOM does not support SVGMatrix
+ describeSkipIf(isJSDOM)('rotation', () => {
+ const matrixToRotation = (element: SVGSVGElement | null) => {
+ if (!element) {
+ throw new Error('Svg element not found');
+ }
+
+ const matrix = new DOMMatrix(getComputedStyle(element).transform);
+ return (Math.atan2(matrix.b, matrix.a) * 180) / Math.PI;
+ };
+
+ describe('horizontal', () => {
+ it('should render a gradient in the correct orientation', () => {
+ const { container } = render();
+ const svg = container.querySelector('svg');
+ expect(matrixToRotation(svg)).to.equal(0);
+ });
+
+ it('should reverse the gradient', () => {
+ const { container } = render();
+ const svg = container.querySelector('svg');
+ expect(matrixToRotation(svg)).to.equal(180);
+ });
+
+ it('should rotate the gradient', () => {
+ const { container } = render();
+ const svg = container.querySelector('svg');
+ expect(matrixToRotation(svg)).to.equal(90);
+ });
+
+ it('should reverse and rotate the gradient', () => {
+ const { container } = render(
+ ,
+ );
+ const svg = container.querySelector('svg');
+ expect(matrixToRotation(svg)).to.equal(-90);
+ });
+ });
+
+ describe('vertical', () => {
+ it('should render a gradient in the correct orientation', () => {
+ const { container } = render(
+ ,
+ );
+ const svg = container.querySelector('svg');
+ expect(matrixToRotation(svg)).to.equal(-90);
+ });
+
+ it('should reverse the gradient', () => {
+ const { container } = render(
+ ,
+ );
+ const svg = container.querySelector('svg');
+ expect(matrixToRotation(svg)).to.equal(90);
+ });
+
+ it('should rotate the gradient', () => {
+ const { container } = render(
+ ,
+ );
+ const svg = container.querySelector('svg');
+ expect(matrixToRotation(svg)).to.equal(0);
+ });
+
+ it('should reverse and rotate the gradient', () => {
+ const { container } = render(
+ ,
+ );
+ const svg = container.querySelector('svg');
+ expect(matrixToRotation(svg)).to.equal(180);
+ });
+ });
+
+ describe('RTL', () => {
+ describe('horizontal', () => {
+ it('should render a gradient in the correct orientation', () => {
+ const { container } = render(, {
+ wrapper: RtlWrapper,
+ });
+ const svg = container.querySelector('svg');
+ // Technically it is -180, but the browser will normalize it to 180
+ expect(matrixToRotation(svg)).to.equal(180);
+ });
+
+ it('should reverse the gradient', () => {
+ const { container } = render(
+ ,
+ { wrapper: RtlWrapper },
+ );
+ const svg = container.querySelector('svg');
+ expect(matrixToRotation(svg)).to.equal(0);
+ });
+
+ it('should rotate the gradient', () => {
+ const { container } = render(
+ ,
+ { wrapper: RtlWrapper },
+ );
+ const svg = container.querySelector('svg');
+ expect(matrixToRotation(svg)).to.equal(90);
+ });
+
+ it('should reverse and rotate the gradient', () => {
+ const { container } = render(
+ ,
+ { wrapper: RtlWrapper },
+ );
+ const svg = container.querySelector('svg');
+ expect(matrixToRotation(svg)).to.equal(-90);
+ });
+ });
+
+ describe('vertical', () => {
+ it('should render a gradient in the correct orientation', () => {
+ const { container } = render(
+ ,
+ { wrapper: RtlWrapper },
+ );
+ const svg = container.querySelector('svg');
+ expect(matrixToRotation(svg)).to.equal(-90);
+ });
+
+ it('should reverse the gradient', () => {
+ const { container } = render(
+ ,
+ { wrapper: RtlWrapper },
+ );
+ const svg = container.querySelector('svg');
+ expect(matrixToRotation(svg)).to.equal(90);
+ });
+
+ it('should rotate the gradient', () => {
+ const { container } = render(
+ ,
+ { wrapper: RtlWrapper },
+ );
+ const svg = container.querySelector('svg');
+ expect(matrixToRotation(svg)).to.equal(180);
+ });
+
+ it('should reverse and rotate the gradient', () => {
+ const { container } = render(
+ ,
+ { wrapper: RtlWrapper },
+ );
+ const svg = container.querySelector('svg');
+ expect(matrixToRotation(svg)).to.equal(0);
+ });
+ });
+ });
+ });
});
function Gradient({ id }: any) {
@@ -43,3 +203,11 @@ function Gradient({ id }: any) {
);
}
+
+function RtlWrapper({ children }: any) {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/packages/x-charts/src/ChartsLabel/ChartsLabelGradient.tsx b/packages/x-charts/src/ChartsLabel/ChartsLabelGradient.tsx
index c842ab1ad7d8e..7ec8c2fa024f5 100644
--- a/packages/x-charts/src/ChartsLabel/ChartsLabelGradient.tsx
+++ b/packages/x-charts/src/ChartsLabel/ChartsLabelGradient.tsx
@@ -3,6 +3,7 @@ import * as React from 'react';
import PropTypes from 'prop-types';
import { styled, SxProps, Theme } from '@mui/material/styles';
import clsx from 'clsx';
+import { useRtl } from '@mui/system/RtlProvider';
import {
ChartsLabelGradientClasses,
useUtilityClasses,
@@ -43,32 +44,40 @@ export interface ChartsLabelGradientProps {
sx?: SxProps;
}
+const applyRtl = (isRtl: boolean | undefined, value: number) => (isRtl ? value - 180 : value);
+
const getRotation = (
direction?: 'vertical' | 'horizontal',
reverse?: boolean,
rotate?: boolean,
+ isRtl?: boolean,
) => {
if (!rotate && reverse) {
- return direction === 'vertical' ? 90 : 180;
+ return direction === 'vertical' ? 90 : applyRtl(isRtl, 180);
}
if (rotate && !reverse) {
- return direction === 'vertical' ? 0 : 90;
+ return direction === 'vertical' ? applyRtl(isRtl, 0) : 90;
}
if (rotate && reverse) {
- return direction === 'vertical' ? 180 : -90;
+ return direction === 'vertical' ? applyRtl(isRtl, 180) : -90;
}
- return direction === 'vertical' ? -90 : 0;
+ return direction === 'vertical' ? -90 : applyRtl(isRtl, 0);
};
const Root = styled('div', {
name: 'MuiChartsLabelGradient',
slot: 'Root',
overridesResolver: (props, styles) => styles.root,
-})<{ ownerState: ChartsLabelGradientProps }>(({ ownerState }) => {
- const rotation = getRotation(ownerState.direction, ownerState.reverse, ownerState.rotate);
+})<{ ownerState: ChartsLabelGradientProps & { isRtl: boolean } }>(({ ownerState }) => {
+ const rotation = getRotation(
+ ownerState.direction,
+ ownerState.reverse,
+ ownerState.rotate,
+ ownerState.isRtl,
+ );
return {
display: 'flex',
@@ -118,11 +127,12 @@ const ChartsLabelGradient = consumeThemeProps(
function ChartsLabelGradient(props: ChartsLabelGradientProps, ref: React.Ref) {
const { gradientId, direction, classes, className, rotate, reverse, thickness, ...other } =
props;
+ const isRtl = useRtl();
return (