diff --git a/changelogOld/CHANGELOG.v6.md b/changelogOld/CHANGELOG.v6.md index df1260fa0d65..f52c6d78a105 100644 --- a/changelogOld/CHANGELOG.v6.md +++ b/changelogOld/CHANGELOG.v6.md @@ -5374,7 +5374,7 @@ You can find more information about the new api, including how to set those tran - [pickers] Clean slots on `PickersArrowSwitcher` component (#5890) @flaviendelangle - [pickers] Fix invalid date error when decreasing `DateField` day (#6071) @alexfauquette - [pickers] Fix mobile section selection (#6207) @oliviertassinari -- [pickers] Fix usage with Typescript 4.8 (#6229) @flaviendelangle +- [pickers] Fix usage with TypeScript 4.8 (#6229) @flaviendelangle - [pickers] Improve error message when no adapter context is found (#6211) @flaviendelangle - [pickers] Remove `valueStr` from the field state (#6142) @flaviendelangle - [pickers] Remove remaining deprecated locale props (#6233) @flaviendelangle diff --git a/docs/next-env.d.ts b/docs/next-env.d.ts index 4f11a03dc6cc..a4a7b3f5cfa2 100644 --- a/docs/next-env.d.ts +++ b/docs/next-env.d.ts @@ -2,4 +2,4 @@ /// // NOTE: This file should not be edited -// see https://nextjs.org/docs/basic-features/typescript for more information. +// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information. diff --git a/docs/public/_headers b/docs/public/_headers index d4afc703021d..a69d43e433d8 100644 --- a/docs/public/_headers +++ b/docs/public/_headers @@ -16,3 +16,6 @@ X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block Referrer-Policy: strict-origin-when-cross-origin + # TODO: progressively reduce the CSP scopes + # Start with a wildcard, using https://github.com/mui/mui-toolpad/blob/f4c4eb046b352e4fc00729c3bed605e671b040c4/packages/toolpad-studio/src/server/index.ts#L241 + Content-Security-Policy: default-src * data: mediastream: blob: filesystem: about: ws: wss: 'unsafe-eval' 'wasm-unsafe-eval' 'unsafe-inline'; script-src * data: blob: 'unsafe-inline' 'unsafe-eval'; script-src-elem * data: blob: 'unsafe-inline'; connect-src * data: blob: 'unsafe-inline'; img-src * data: blob: 'unsafe-inline'; media-src * data: blob: 'unsafe-inline'; frame-src * data: blob: ; style-src * data: blob: 'unsafe-inline'; font-src * data: blob: 'unsafe-inline'; frame-ancestors *; diff --git a/packages/eslint-plugin-material-ui/package.json b/packages/eslint-plugin-material-ui/package.json index 2a8687a71bd3..1f03a292d632 100644 --- a/packages/eslint-plugin-material-ui/package.json +++ b/packages/eslint-plugin-material-ui/package.json @@ -14,7 +14,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/mui/mui-x.git" + "url": "git+https://github.com/mui/mui-x.git" }, "license": "MIT" } diff --git a/packages/x-charts-pro/package.json b/packages/x-charts-pro/package.json index 4558271d8457..49af8fa5d19b 100644 --- a/packages/x-charts-pro/package.json +++ b/packages/x-charts-pro/package.json @@ -35,7 +35,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/mui/mui-x.git", + "url": "git+https://github.com/mui/mui-x.git", "directory": "packages/x-charts-pro" }, "dependencies": { diff --git a/packages/x-charts-vendor/package.json b/packages/x-charts-vendor/package.json index d7a322bfbccb..0266a534fcd7 100644 --- a/packages/x-charts-vendor/package.json +++ b/packages/x-charts-vendor/package.json @@ -11,7 +11,7 @@ ], "repository": { "type": "git", - "url": "https://github.com/mui/mui-x.git", + "url": "git+https://github.com/mui/mui-x.git", "directory": "packages/x-charts-vendor" }, "license": "MIT AND ISC", diff --git a/packages/x-charts/package.json b/packages/x-charts/package.json index 8c0b7e009c0e..61ae0733fcef 100644 --- a/packages/x-charts/package.json +++ b/packages/x-charts/package.json @@ -35,7 +35,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/mui/mui-x.git", + "url": "git+https://github.com/mui/mui-x.git", "directory": "packages/x-charts" }, "dependencies": { diff --git a/packages/x-codemod/package.json b/packages/x-codemod/package.json index 7a400bf3f38a..385c02d2bcfb 100644 --- a/packages/x-codemod/package.json +++ b/packages/x-codemod/package.json @@ -22,7 +22,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/mui/mui-x.git", + "url": "git+https://github.com/mui/mui-x.git", "directory": "packages/x-codemod" }, "license": "MIT", diff --git a/packages/x-data-grid-generator/package.json b/packages/x-data-grid-generator/package.json index 17179ae34704..faea4d9752fe 100644 --- a/packages/x-data-grid-generator/package.json +++ b/packages/x-data-grid-generator/package.json @@ -29,7 +29,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/mui/mui-x.git", + "url": "git+https://github.com/mui/mui-x.git", "directory": "packages/x-data-grid-generator" }, "dependencies": { diff --git a/packages/x-data-grid-premium/package.json b/packages/x-data-grid-premium/package.json index 415947ca3542..cb083a823d2d 100644 --- a/packages/x-data-grid-premium/package.json +++ b/packages/x-data-grid-premium/package.json @@ -39,7 +39,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/mui/mui-x.git", + "url": "git+https://github.com/mui/mui-x.git", "directory": "packages/x-data-grid-premium" }, "dependencies": { diff --git a/packages/x-data-grid-pro/package.json b/packages/x-data-grid-pro/package.json index 61ac8f80e401..59f60a36935e 100644 --- a/packages/x-data-grid-pro/package.json +++ b/packages/x-data-grid-pro/package.json @@ -39,7 +39,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/mui/mui-x.git", + "url": "git+https://github.com/mui/mui-x.git", "directory": "packages/x-data-grid-pro" }, "dependencies": { diff --git a/packages/x-data-grid/package.json b/packages/x-data-grid/package.json index 7a4dad558463..ef8e2c3e1554 100644 --- a/packages/x-data-grid/package.json +++ b/packages/x-data-grid/package.json @@ -43,7 +43,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/mui/mui-x.git", + "url": "git+https://github.com/mui/mui-x.git", "directory": "packages/x-data-grid" }, "dependencies": { diff --git a/packages/x-data-grid/src/components/cell/GridCell.tsx b/packages/x-data-grid/src/components/cell/GridCell.tsx index 81ddc96ba4fa..089932efa4d0 100644 --- a/packages/x-data-grid/src/components/cell/GridCell.tsx +++ b/packages/x-data-grid/src/components/cell/GridCell.tsx @@ -8,6 +8,7 @@ import { unstable_capitalize as capitalize, } from '@mui/utils'; import { fastMemo } from '@mui/x-internals/fastMemo'; +import { useRtl } from '@mui/system/RtlProvider'; import { doesSupportPreventScroll } from '../../utils/doesSupportPreventScroll'; import { getDataGridUtilityClass, gridClasses } from '../../constants/gridClasses'; import { @@ -175,6 +176,7 @@ const GridCell = React.forwardRef(function GridCe const apiRef = useGridApiContext(); const rootProps = useGridRootProps(); + const isRtl = useRtl(); const field = column.field; @@ -334,16 +336,21 @@ const GridCell = React.forwardRef(function GridCe ...styleProp, }; - if (pinnedPosition === PinnedPosition.LEFT) { - cellStyle.left = pinnedOffset; - } + const isLeftPinned = pinnedPosition === PinnedPosition.LEFT; + const isRightPinned = pinnedPosition === PinnedPosition.RIGHT; + + if (isLeftPinned || isRightPinned) { + let side: 'left' | 'right' = isLeftPinned ? 'left' : 'right'; + + if (isRtl) { + side = isLeftPinned ? 'right' : 'left'; + } - if (pinnedPosition === PinnedPosition.RIGHT) { - cellStyle.right = pinnedOffset; + cellStyle[side] = pinnedOffset; } return cellStyle; - }, [width, isNotVisible, styleProp, pinnedOffset, pinnedPosition]); + }, [width, isNotVisible, styleProp, pinnedOffset, pinnedPosition, isRtl]); React.useEffect(() => { if (!hasFocus || cellMode === GridCellModes.Edit) { diff --git a/packages/x-data-grid/src/hooks/features/columnHeaders/useGridColumnHeaders.tsx b/packages/x-data-grid/src/hooks/features/columnHeaders/useGridColumnHeaders.tsx index c6bb0d81a9e6..d84c751c4175 100644 --- a/packages/x-data-grid/src/hooks/features/columnHeaders/useGridColumnHeaders.tsx +++ b/packages/x-data-grid/src/hooks/features/columnHeaders/useGridColumnHeaders.tsx @@ -108,12 +108,7 @@ export const useGridColumnHeaders = (props: UseGridColumnHeadersProps) => { const renderContext = useGridSelector(apiRef, gridRenderContextColumnsSelector); const pinnedColumns = useGridSelector(apiRef, gridVisiblePinnedColumnDefinitionsSelector); const columnsLookup = useGridSelector(apiRef, gridColumnLookupSelector); - const offsetLeft = computeOffsetLeft( - columnPositions, - renderContext, - isRtl, - pinnedColumns.left.length, - ); + const offsetLeft = computeOffsetLeft(columnPositions, renderContext, pinnedColumns.left.length); const gridHasFiller = dimensions.columnsTotalWidth < dimensions.viewportOuterSize.width; React.useEffect(() => { @@ -230,7 +225,11 @@ export const useGridColumnHeaders = (props: UseGridColumnHeadersProps) => { computedWidth: number; }) => { let style: React.CSSProperties | undefined; - if (pinnedPosition === 'left' || pinnedPosition === 'right') { + + const isLeftPinned = pinnedPosition === GridPinnedColumnPosition.LEFT; + const isRightPinned = pinnedPosition === GridPinnedColumnPosition.RIGHT; + + if (isLeftPinned || isRightPinned) { const pinnedOffset = getPinnedCellOffset( pinnedPosition, computedWidth, @@ -238,12 +237,18 @@ export const useGridColumnHeaders = (props: UseGridColumnHeadersProps) => { columnPositions, dimensions, ); + let side = isLeftPinned ? 'left' : 'right'; + + if (isRtl) { + side = isLeftPinned ? 'right' : 'left'; + } + if (pinnedPosition === 'left') { - style = { left: pinnedOffset }; + style = { [side]: pinnedOffset }; } if (pinnedPosition === 'right') { - style = { right: pinnedOffset }; + style = { [side]: pinnedOffset }; } } diff --git a/packages/x-data-grid/src/hooks/features/columnResize/useGridColumnResize.tsx b/packages/x-data-grid/src/hooks/features/columnResize/useGridColumnResize.tsx index 4a501e432416..aa79485f5a4a 100644 --- a/packages/x-data-grid/src/hooks/features/columnResize/useGridColumnResize.tsx +++ b/packages/x-data-grid/src/hooks/features/columnResize/useGridColumnResize.tsx @@ -456,8 +456,14 @@ export const useGridColumnResize = ( refs.cellElements = findGridCellElementsFromCol(refs.columnHeaderElement, apiRef.current); - refs.fillerLeft = findGridElement(apiRef.current, 'filler--pinnedLeft'); - refs.fillerRight = findGridElement(apiRef.current, 'filler--pinnedRight'); + refs.fillerLeft = findGridElement( + apiRef.current, + isRtl ? 'filler--pinnedRight' : 'filler--pinnedLeft', + ); + refs.fillerRight = findGridElement( + apiRef.current, + isRtl ? 'filler--pinnedLeft' : 'filler--pinnedRight', + ); const pinnedPosition = apiRef.current.unstable_applyPipeProcessors( 'isColumnPinned', @@ -468,20 +474,20 @@ export const useGridColumnResize = ( refs.leftPinnedCellsAfter = pinnedPosition !== GridPinnedColumnPosition.LEFT ? [] - : findLeftPinnedCellsAfterCol(apiRef.current, refs.columnHeaderElement); + : findLeftPinnedCellsAfterCol(apiRef.current, refs.columnHeaderElement, isRtl); refs.rightPinnedCellsBefore = pinnedPosition !== GridPinnedColumnPosition.RIGHT ? [] - : findRightPinnedCellsBeforeCol(apiRef.current, refs.columnHeaderElement); + : findRightPinnedCellsBeforeCol(apiRef.current, refs.columnHeaderElement, isRtl); refs.leftPinnedHeadersAfter = pinnedPosition !== GridPinnedColumnPosition.LEFT ? [] - : findLeftPinnedHeadersAfterCol(apiRef.current, refs.columnHeaderElement); + : findLeftPinnedHeadersAfterCol(apiRef.current, refs.columnHeaderElement, isRtl); refs.rightPinnedHeadersBefore = pinnedPosition !== GridPinnedColumnPosition.RIGHT ? [] - : findRightPinnedHeadersBeforeCol(apiRef.current, refs.columnHeaderElement); + : findRightPinnedHeadersBeforeCol(apiRef.current, refs.columnHeaderElement, isRtl); resizeDirection.current = getResizeDirection(separator, isRtl); diff --git a/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx b/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx index cdb2ca3029df..53a8b9cd6c56 100644 --- a/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx +++ b/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx @@ -466,7 +466,6 @@ export const useGridVirtualScroller = () => { const offsetLeft = computeOffsetLeft( columnPositions, currentRenderContext, - isRtl, pinnedColumns.left.length, ); const showBottomBorder = isLastVisibleInSection && params.position === 'top'; @@ -939,14 +938,11 @@ export function areRenderContextsEqual(context1: GridRenderContext, context2: Gr export function computeOffsetLeft( columnPositions: number[], renderContext: GridColumnsRenderContext, - isRtl: boolean, pinnedLeftLength: number, ) { - const factor = isRtl ? -1 : 1; const left = - factor * (columnPositions[renderContext.firstColumnIndex] ?? 0) - + (columnPositions[renderContext.firstColumnIndex] ?? 0) - (columnPositions[pinnedLeftLength] ?? 0); - return Math.abs(left); } diff --git a/packages/x-data-grid/src/utils/domUtils.ts b/packages/x-data-grid/src/utils/domUtils.ts index 5d19c58809cb..0b002536f883 100644 --- a/packages/x-data-grid/src/utils/domUtils.ts +++ b/packages/x-data-grid/src/utils/domUtils.ts @@ -166,23 +166,31 @@ const findPinnedCells = ({ return cells; }; -export function findLeftPinnedCellsAfterCol(api: GridPrivateApiCommunity, col: HTMLElement) { +export function findLeftPinnedCellsAfterCol( + api: GridPrivateApiCommunity, + col: HTMLElement, + isRtl: boolean, +) { const colIndex = parseCellColIndex(col); return findPinnedCells({ api, colIndex, - position: 'left', - filterFn: (index) => index > colIndex!, + position: isRtl ? 'right' : 'left', + filterFn: (index) => (isRtl ? index < colIndex! : index > colIndex!), }); } -export function findRightPinnedCellsBeforeCol(api: GridPrivateApiCommunity, col: HTMLElement) { +export function findRightPinnedCellsBeforeCol( + api: GridPrivateApiCommunity, + col: HTMLElement, + isRtl: boolean, +) { const colIndex = parseCellColIndex(col); return findPinnedCells({ api, colIndex, - position: 'right', - filterFn: (index) => index < colIndex!, + position: isRtl ? 'left' : 'right', + filterFn: (index) => (isRtl ? index > colIndex! : index < colIndex!), }); } @@ -218,23 +226,31 @@ const findPinnedHeaders = ({ return elements; }; -export function findLeftPinnedHeadersAfterCol(api: GridPrivateApiCommunity, col: HTMLElement) { +export function findLeftPinnedHeadersAfterCol( + api: GridPrivateApiCommunity, + col: HTMLElement, + isRtl: boolean, +) { const colIndex = parseCellColIndex(col); return findPinnedHeaders({ api, - position: 'left', + position: isRtl ? 'right' : 'left', colIndex, - filterFn: (index) => index > colIndex!, + filterFn: (index) => (isRtl ? index < colIndex! : index > colIndex!), }); } -export function findRightPinnedHeadersBeforeCol(api: GridPrivateApiCommunity, col: HTMLElement) { +export function findRightPinnedHeadersBeforeCol( + api: GridPrivateApiCommunity, + col: HTMLElement, + isRtl: boolean, +) { const colIndex = parseCellColIndex(col); return findPinnedHeaders({ api, - position: 'right', + position: isRtl ? 'left' : 'right', colIndex, - filterFn: (index) => index < colIndex!, + filterFn: (index) => (isRtl ? index > colIndex! : index < colIndex!), }); } diff --git a/packages/x-date-pickers-pro/package.json b/packages/x-date-pickers-pro/package.json index 97847f806565..cddcbb2de174 100644 --- a/packages/x-date-pickers-pro/package.json +++ b/packages/x-date-pickers-pro/package.json @@ -38,7 +38,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/mui/mui-x.git", + "url": "git+https://github.com/mui/mui-x.git", "directory": "packages/x-date-pickers-pro" }, "dependencies": { diff --git a/packages/x-date-pickers/package.json b/packages/x-date-pickers/package.json index ac710ff06dc6..4a9a3e621999 100644 --- a/packages/x-date-pickers/package.json +++ b/packages/x-date-pickers/package.json @@ -41,7 +41,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/mui/mui-x.git", + "url": "git+https://github.com/mui/mui-x.git", "directory": "packages/x-date-pickers" }, "dependencies": { diff --git a/packages/x-internals/package.json b/packages/x-internals/package.json index df9ccac85b63..3a4d212c7b44 100644 --- a/packages/x-internals/package.json +++ b/packages/x-internals/package.json @@ -37,7 +37,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/mui/mui-x.git", + "url": "git+https://github.com/mui/mui-x.git", "directory": "packages/x-internals" }, "dependencies": { diff --git a/packages/x-license/package.json b/packages/x-license/package.json index d9573e61eea3..797ed24e7527 100644 --- a/packages/x-license/package.json +++ b/packages/x-license/package.json @@ -30,7 +30,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/mui/mui-x.git", + "url": "git+https://github.com/mui/mui-x.git", "directory": "packages/x-license" }, "dependencies": { diff --git a/packages/x-tree-view-pro/package.json b/packages/x-tree-view-pro/package.json index 8441d0797527..038c43acf697 100644 --- a/packages/x-tree-view-pro/package.json +++ b/packages/x-tree-view-pro/package.json @@ -39,7 +39,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/mui/mui-x.git", + "url": "git+https://github.com/mui/mui-x.git", "directory": "packages/x-tree-view-pro" }, "dependencies": { diff --git a/packages/x-tree-view/package.json b/packages/x-tree-view/package.json index 5b8f5761c9c8..346ca81fd0aa 100644 --- a/packages/x-tree-view/package.json +++ b/packages/x-tree-view/package.json @@ -39,7 +39,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/mui/mui-x.git", + "url": "git+https://github.com/mui/mui-x.git", "directory": "packages/x-tree-view" }, "dependencies": { diff --git a/test/regressions/data-grid/DataGridRTLPinnedColumns.js b/test/regressions/data-grid/DataGridRTLPinnedColumns.js new file mode 100644 index 000000000000..bfe199c76be7 --- /dev/null +++ b/test/regressions/data-grid/DataGridRTLPinnedColumns.js @@ -0,0 +1,83 @@ +import * as React from 'react'; +import { prefixer } from 'stylis'; +import rtlPlugin from 'stylis-plugin-rtl'; +import { useGridApiRef, DataGridPro } from '@mui/x-data-grid-pro'; +import { arSD } from '@mui/x-data-grid/locales'; +import createCache from '@emotion/cache'; +import { CacheProvider } from '@emotion/react'; +import { createTheme, ThemeProvider, useTheme } from '@mui/material/styles'; + +// Create rtl cache +const cacheRtl = createCache({ + key: 'data-grid-rtl-demo', + stylisPlugins: [prefixer, rtlPlugin], +}); + +const columns = [ + { + field: 'id', + headerName: 'تعريف', + width: 150, + }, + { + field: 'name', + headerName: 'اسم', + width: 150, + }, + { + field: 'age', + headerName: 'عمر', + valueGetter: (value) => `${value} سنوات`, + width: 150, + }, + { + field: 'occupation', + headerName: 'المهنة', + width: 150, + }, + { + field: 'gender', + headerName: 'جنس', + width: 150, + }, +]; + +const rows = [ + { id: 1, name: 'سارہ', age: 35, occupation: 'معلم', gender: 'أنثى' }, + { id: 2, name: 'زید', age: 42, occupation: 'مهندس', gender: 'ذكر' }, + { id: 3, name: 'علی', age: 33, occupation: 'محاسب', gender: 'ذكر' }, + { id: 4, name: 'فاطمہ', age: 25, occupation: 'معلم', gender: 'أنثى' }, + { id: 5, name: 'ایندریو', age: 65, occupation: 'مهندس', gender: 'ذكر' }, +]; + +export default function DataGridRTLPinnedColumns() { + const apiRef = useGridApiRef(); + const existingTheme = useTheme(); + const theme = React.useMemo( + () => + createTheme({}, arSD, existingTheme, { + direction: 'rtl', + }), + [existingTheme], + ); + + return ( + + +
+ +
+
+
+ ); +}