diff --git a/examples/demo/package.json b/examples/demo/package.json index e7c1f1823e9..7156f49e4b9 100644 --- a/examples/demo/package.json +++ b/examples/demo/package.json @@ -29,8 +29,8 @@ "react": "^19.0.0", "react-admin": "^5.0.0", "react-dom": "^19.0.0", - "react-router": "^6.22.0", - "react-router-dom": "^6.22.0", + "react-router": "^7.1.1", + "react-router-dom": "^7.1.1", "recharts": "^2.15.0" }, "scripts": { diff --git a/examples/demo/src/categories/LinkToRelatedProducts.tsx b/examples/demo/src/categories/LinkToRelatedProducts.tsx index bf502f5f093..110c9beac01 100644 --- a/examples/demo/src/categories/LinkToRelatedProducts.tsx +++ b/examples/demo/src/categories/LinkToRelatedProducts.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import Button from '@mui/material/Button'; -import { Link } from 'react-router-dom'; +import { Link } from 'react-router'; import { useTranslate, useRecordContext } from 'react-admin'; import { stringify } from 'query-string'; diff --git a/examples/demo/src/dashboard/CardWithIcon.tsx b/examples/demo/src/dashboard/CardWithIcon.tsx index bb0c4446865..494db1ea786 100644 --- a/examples/demo/src/dashboard/CardWithIcon.tsx +++ b/examples/demo/src/dashboard/CardWithIcon.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { FC, createElement } from 'react'; import { Card, Box, Typography, Divider } from '@mui/material'; -import { Link, To } from 'react-router-dom'; +import { Link, To } from 'react-router'; import { ReactNode } from 'react'; interface Props { diff --git a/examples/demo/src/dashboard/NewCustomers.tsx b/examples/demo/src/dashboard/NewCustomers.tsx index f357ce8b816..26ff1ce0281 100644 --- a/examples/demo/src/dashboard/NewCustomers.tsx +++ b/examples/demo/src/dashboard/NewCustomers.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { Avatar, Box, Button } from '@mui/material'; import CustomerIcon from '@mui/icons-material/PersonAdd'; -import { Link } from 'react-router-dom'; +import { Link } from 'react-router'; import { ListBase, WithListContext, diff --git a/examples/demo/src/dashboard/PendingOrder.tsx b/examples/demo/src/dashboard/PendingOrder.tsx index 49a7ced13c6..51362c9ffa6 100644 --- a/examples/demo/src/dashboard/PendingOrder.tsx +++ b/examples/demo/src/dashboard/PendingOrder.tsx @@ -8,7 +8,7 @@ import { Box, ListItemButton, } from '@mui/material'; -import { Link } from 'react-router-dom'; +import { Link } from 'react-router'; import { useTranslate, useReference } from 'react-admin'; import { Customer, Order } from '../types'; diff --git a/examples/demo/src/dashboard/PendingReviews.tsx b/examples/demo/src/dashboard/PendingReviews.tsx index 2a717fd80f8..bae21556814 100644 --- a/examples/demo/src/dashboard/PendingReviews.tsx +++ b/examples/demo/src/dashboard/PendingReviews.tsx @@ -10,7 +10,7 @@ import { ListItemText, } from '@mui/material'; import CommentIcon from '@mui/icons-material/Comment'; -import { Link } from 'react-router-dom'; +import { Link } from 'react-router'; import { ReferenceField, diff --git a/examples/demo/src/layout/Login.tsx b/examples/demo/src/layout/Login.tsx index 4f145f99558..eb46ff08430 100644 --- a/examples/demo/src/layout/Login.tsx +++ b/examples/demo/src/layout/Login.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { useState } from 'react'; -import { useLocation } from 'react-router-dom'; +import { useLocation } from 'react-router'; import { Avatar, diff --git a/examples/demo/src/products/GridList.tsx b/examples/demo/src/products/GridList.tsx index 5a3649e6790..bc1e1c8dcc0 100644 --- a/examples/demo/src/products/GridList.tsx +++ b/examples/demo/src/products/GridList.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { useTheme, useMediaQuery } from '@mui/material'; import { Box, ImageList, ImageListItem, ImageListItemBar } from '@mui/material'; import { useCreatePath, NumberField, useListContext } from 'react-admin'; -import { Link } from 'react-router-dom'; +import { Link } from 'react-router'; const GridList = () => { const { isPending } = useListContext(); diff --git a/examples/demo/src/reviews/ReviewList.tsx b/examples/demo/src/reviews/ReviewList.tsx index 0accf1c94a3..ae4f018a79e 100644 --- a/examples/demo/src/reviews/ReviewList.tsx +++ b/examples/demo/src/reviews/ReviewList.tsx @@ -9,7 +9,7 @@ import { TopToolbar, useDefaultTitle, } from 'react-admin'; -import { matchPath, useLocation, useNavigate } from 'react-router-dom'; +import { matchPath, useLocation, useNavigate } from 'react-router'; import { Box, Drawer, useMediaQuery, Theme } from '@mui/material'; import ReviewListMobile from './ReviewListMobile'; diff --git a/examples/demo/src/segments/LinkToRelatedCustomers.tsx b/examples/demo/src/segments/LinkToRelatedCustomers.tsx index 44bc745cfd6..7b6db657efb 100644 --- a/examples/demo/src/segments/LinkToRelatedCustomers.tsx +++ b/examples/demo/src/segments/LinkToRelatedCustomers.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { Button } from '@mui/material'; -import { Link } from 'react-router-dom'; +import { Link } from 'react-router'; import { useTranslate } from 'react-admin'; import { stringify } from 'query-string'; diff --git a/examples/tutorial/package.json b/examples/tutorial/package.json index 1105a69d397..8ed28f92f70 100644 --- a/examples/tutorial/package.json +++ b/examples/tutorial/package.json @@ -14,7 +14,9 @@ "ra-data-json-server": "^5.0.0", "react": "^19.0.0", "react-admin": "^5.0.0", - "react-dom": "^19.0.0" + "react-dom": "^19.0.0", + "react-router": "^7.1.1", + "react-router-dom": "^7.1.1" }, "devDependencies": { "@types/react": "^18.3.3", diff --git a/packages/ra-core/package.json b/packages/ra-core/package.json index 09b82787f7a..d39884a88cd 100644 --- a/packages/ra-core/package.json +++ b/packages/ra-core/package.json @@ -53,8 +53,8 @@ "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0", "react-hook-form": "^7.53.0", - "react-router": "^6.22.0", - "react-router-dom": "^6.22.0" + "react-router": "^6.22.0 || ^7.0.0", + "react-router-dom": "^6.22.0 || ^7.0.0" }, "dependencies": { "@tanstack/react-query": "^5.21.7", diff --git a/packages/ra-ui-materialui/package.json b/packages/ra-ui-materialui/package.json index b0096951ec4..be5f2b4b738 100644 --- a/packages/ra-ui-materialui/package.json +++ b/packages/ra-ui-materialui/package.json @@ -60,8 +60,8 @@ "react-dom": "^18.0.0 || ^19.0.0", "react-hook-form": "*", "react-is": "^18.0.0 || ^19.0.0", - "react-router": "^6.22.0", - "react-router-dom": "^6.22.0" + "react-router": "^6.22.0 || ^7.0.0", + "react-router-dom": "^6.22.0 || ^7.0.0" }, "dependencies": { "@tanstack/react-query": "^5.21.7", diff --git a/packages/react-admin/package.json b/packages/react-admin/package.json index a34200bfff5..19dc88f7d45 100644 --- a/packages/react-admin/package.json +++ b/packages/react-admin/package.json @@ -26,8 +26,12 @@ "watch": "tsc --outDir dist/esm --module es2015 --watch" }, "devDependencies": { + "@mui/icons-material": "^5.16.12", + "@mui/material": "^5.16.12", "cross-env": "^5.2.0", "expect": "^27.4.6", + "react-router": "^6.25.1", + "react-router-dom": "^6.25.1", "rimraf": "^3.0.2", "typescript": "^5.1.3" }, @@ -43,8 +47,8 @@ "ra-language-english": "^5.4.3", "ra-ui-materialui": "^5.4.3", "react-hook-form": "^7.53.0", - "react-router": "^6.22.0", - "react-router-dom": "^6.22.0" + "react-router": "^6.22.0 || ^7.0.0", + "react-router-dom": "^6.22.0 || ^7.0.0" }, "gitHead": "587df4c27bfcec4a756df4f95e5fc14728dfc0d7" } diff --git a/packages/react-admin/src/Admin.spec.tsx b/packages/react-admin/src/Admin.spec.tsx index 985f5540253..b02d0d845c8 100644 --- a/packages/react-admin/src/Admin.spec.tsx +++ b/packages/react-admin/src/Admin.spec.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { render, screen } from '@testing-library/react'; +import { fireEvent, render, screen } from '@testing-library/react'; import { Basic, InsideRouter, SubPath, DefaultError } from './Admin.stories'; @@ -25,7 +25,7 @@ describe('', () => { it('works when mounted in a subPath', async () => { render(); - screen.getByText('Go to admin').click(); + fireEvent.click(await screen.findByText('Go to admin')); await screen.findByText('Post List'); screen.getAllByText('Comments')[0].click(); await screen.findByText('Comment List'); diff --git a/test-setup.js b/test-setup.js index 750b1267520..ef6fdc8cab0 100644 --- a/test-setup.js +++ b/test-setup.js @@ -26,3 +26,10 @@ global.Request = Request; /** Mock scrollTo as it is not supported by JSDOM */ global.scrollTo = jest.fn(); + +/** Mock TextEncoder as it is not supported by JSDOM */ +if (!global.TextEncoder || !global.TextDecoder) { + const { TextDecoder, TextEncoder } = require('node:util'); + global.TextEncoder = TextEncoder; + global.TextDecoder = TextDecoder; +} diff --git a/yarn.lock b/yarn.lock index c18e951d778..b4bcc62810b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2892,7 +2892,7 @@ __metadata: languageName: node linkType: hard -"@mui/icons-material@npm:^5.16.12 || ^6.0.0, @mui/icons-material@npm:^6.0.0": +"@mui/icons-material@npm:^6.0.0": version: 6.3.1 resolution: "@mui/icons-material@npm:6.3.1" dependencies: @@ -2941,7 +2941,7 @@ __metadata: languageName: node linkType: hard -"@mui/material@npm:^5.16.12 || ^6.0.0, @mui/material@npm:^6.0.0": +"@mui/material@npm:^6.0.0": version: 6.3.1 resolution: "@mui/material@npm:6.3.1" dependencies: @@ -4883,6 +4883,13 @@ __metadata: languageName: node linkType: hard +"@types/cookie@npm:^0.6.0": + version: 0.6.0 + resolution: "@types/cookie@npm:0.6.0" + checksum: 5b326bd0188120fb32c0be086b141b1481fec9941b76ad537f9110e10d61ee2636beac145463319c71e4be67a17e85b81ca9e13ceb6e3bb63b93d16824d6c149 + languageName: node + linkType: hard + "@types/d3-array@npm:^3.0.3": version: 3.2.1 resolution: "@types/d3-array@npm:3.2.1" @@ -7740,6 +7747,13 @@ __metadata: languageName: node linkType: hard +"cookie@npm:^1.0.1": + version: 1.0.2 + resolution: "cookie@npm:1.0.2" + checksum: fd25fe79e8fbcfcaf6aa61cd081c55d144eeeba755206c058682257cb38c4bd6795c6620de3f064c740695bb65b7949ebb1db7a95e4636efb8357a335ad3f54b + languageName: node + linkType: hard + "core-js-compat@npm:^3.20.0, core-js-compat@npm:^3.31.0, core-js-compat@npm:^3.36.1": version: 3.37.1 resolution: "core-js-compat@npm:3.37.1" @@ -8560,8 +8574,8 @@ __metadata: react: "npm:^19.0.0" react-admin: "npm:^5.0.0" react-dom: "npm:^19.0.0" - react-router: "npm:^6.22.0" - react-router-dom: "npm:^6.22.0" + react-router: "npm:^7.1.1" + react-router-dom: "npm:^7.1.1" recharts: "npm:^2.15.0" rewire: "npm:^5.0.0" rollup-plugin-visualizer: "npm:^5.12.0" @@ -16163,8 +16177,8 @@ __metadata: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 react-hook-form: ^7.53.0 - react-router: ^6.22.0 - react-router-dom: ^6.22.0 + react-router: ^6.22.0 || ^7.0.0 + react-router-dom: ^6.22.0 || ^7.0.0 languageName: unknown linkType: soft @@ -16442,8 +16456,8 @@ __metadata: react-dom: ^18.0.0 || ^19.0.0 react-hook-form: "*" react-is: ^18.0.0 || ^19.0.0 - react-router: ^6.22.0 - react-router-dom: ^6.22.0 + react-router: ^6.22.0 || ^7.0.0 + react-router-dom: ^6.22.0 || ^7.0.0 languageName: unknown linkType: soft @@ -16584,8 +16598,8 @@ __metadata: version: 0.0.0-use.local resolution: "react-admin@workspace:packages/react-admin" dependencies: - "@mui/icons-material": "npm:^5.16.12 || ^6.0.0" - "@mui/material": "npm:^5.16.12 || ^6.0.0" + "@mui/icons-material": "npm:^5.16.12" + "@mui/material": "npm:^5.16.12" cross-env: "npm:^5.2.0" expect: "npm:^27.4.6" ra-core: "npm:^5.4.3" @@ -16593,8 +16607,8 @@ __metadata: ra-language-english: "npm:^5.4.3" ra-ui-materialui: "npm:^5.4.3" react-hook-form: "npm:^7.53.0" - react-router: "npm:^6.22.0" - react-router-dom: "npm:^6.22.0" + react-router: "npm:^6.25.1" + react-router-dom: "npm:^6.25.1" rimraf: "npm:^3.0.2" typescript: "npm:^5.1.3" peerDependencies: @@ -16833,6 +16847,18 @@ __metadata: languageName: node linkType: hard +"react-router-dom@npm:^7.1.1": + version: 7.1.1 + resolution: "react-router-dom@npm:7.1.1" + dependencies: + react-router: "npm:7.1.1" + peerDependencies: + react: ">=18" + react-dom: ">=18" + checksum: 2dc5b231dd21aab21378c615b1e373149007d173e90db984e6f708b5ee4b28923b3cf88ce7d6f727be927829b37ba37c01436f9f7abeb84ba3d1bfc9ecd4bc72 + languageName: node + linkType: hard + "react-router@npm:6.25.1, react-router@npm:^6.22.0, react-router@npm:^6.25.1": version: 6.25.1 resolution: "react-router@npm:6.25.1" @@ -16844,6 +16870,24 @@ __metadata: languageName: node linkType: hard +"react-router@npm:7.1.1, react-router@npm:^7.1.1": + version: 7.1.1 + resolution: "react-router@npm:7.1.1" + dependencies: + "@types/cookie": "npm:^0.6.0" + cookie: "npm:^1.0.1" + set-cookie-parser: "npm:^2.6.0" + turbo-stream: "npm:2.4.0" + peerDependencies: + react: ">=18" + react-dom: ">=18" + peerDependenciesMeta: + react-dom: + optional: true + checksum: 39f4859670f286eb2eac29e5830c1f730405701fca0808e5db853ec05e54e55a848c764e10ffd14a7b9b3b2154a0d6449656d7f208b9b3e4b2af780e07bf57a8 + languageName: node + linkType: hard + "react-simple-animate@npm:^3.3.12, react-simple-animate@npm:^3.5.3": version: 3.5.3 resolution: "react-simple-animate@npm:3.5.3" @@ -17821,6 +17865,13 @@ __metadata: languageName: node linkType: hard +"set-cookie-parser@npm:^2.6.0": + version: 2.7.1 + resolution: "set-cookie-parser@npm:2.7.1" + checksum: 060c198c4c92547ac15988256f445eae523f57f2ceefeccf52d30d75dedf6bff22b9c26f756bd44e8e560d44ff4ab2130b178bd2e52ef5571bf7be3bd7632d9a + languageName: node + linkType: hard + "set-function-length@npm:^1.2.1": version: 1.2.2 resolution: "set-function-length@npm:1.2.2" @@ -19044,6 +19095,13 @@ __metadata: languageName: node linkType: hard +"turbo-stream@npm:2.4.0": + version: 2.4.0 + resolution: "turbo-stream@npm:2.4.0" + checksum: e68b2569f1f16e6e9633d090c6024b2ae9f0e97bfeacb572451ca3732e120ebbb546f3bc4afc717c46cb57b5aea6104e04ef497f9912eef6a7641e809518e98a + languageName: node + linkType: hard + "tutorial@workspace:examples/tutorial": version: 0.0.0-use.local resolution: "tutorial@workspace:examples/tutorial" @@ -19057,6 +19115,8 @@ __metadata: react: "npm:^19.0.0" react-admin: "npm:^5.0.0" react-dom: "npm:^19.0.0" + react-router: "npm:^7.1.1" + react-router-dom: "npm:^7.1.1" typescript: "npm:^5.1.3" vite: "npm:^5.0.11" languageName: unknown