diff --git a/.changeset/sixty-brooms-study.md b/.changeset/sixty-brooms-study.md new file mode 100644 index 0000000000..2759d9bb89 --- /dev/null +++ b/.changeset/sixty-brooms-study.md @@ -0,0 +1,30 @@ +--- +'@commercetools-uikit/async-creatable-select-field': major +'@commercetools-uikit/localized-rich-text-input': major +'@commercetools-uikit/async-select-field': major +'@commercetools-uikit/secondary-button': major +'@commercetools-uikit/primary-action-dropdown': major +'@commercetools-uikit/link-button': major +'@commercetools-uikit/select-input': major +'@commercetools-uikit/icons': major +'@commercetools-uikit/card': major +'@commercetools-uikit/link': major +'@commercetools-uikit/tag': major +'visual-testing-app': major +'@commercetools-uikit/buttons': major +'@commercetools-uikit/fields': major +'@commercetools-uikit/inputs': major +'@commercetools-frontend/ui-kit': major +--- + +These changes introduce a migration from react-router v5 to v6. The most obvious change is how the component is now used. Unlike the the pattern in v5 where the `to` props in a nested route requires you to manually interpolate `match.url` for a relative route, v6 accepts a string where all urls are automatically relative routes. + +```jsx +// v5: relative path requires you to manually interpolate +My Profile +``` + +```jsx +// v6: directly passed string is automatically interpreted as relative path +My Profile +``` diff --git a/design-system/src/theme-provider.visualroute.jsx b/design-system/src/theme-provider.visualroute.jsx index f0f5061b9c..651723b0f8 100644 --- a/design-system/src/theme-provider.visualroute.jsx +++ b/design-system/src/theme-provider.visualroute.jsx @@ -1,6 +1,6 @@ import { useState } from 'react'; import { useTheme, designTokens } from '@commercetools-uikit/design-system'; -import { Switch, Route } from 'react-router'; +import { Routes, Route } from 'react-router'; import kebabCase from 'lodash/kebabCase'; import PropTypes from 'prop-types'; import { @@ -191,8 +191,8 @@ const InteractiveRoute = () => { }; export const component = () => ( - - - - + + } /> + } /> + ); diff --git a/package.json b/package.json index f7bf56694b..ee7e185151 100644 --- a/package.json +++ b/package.json @@ -142,7 +142,7 @@ "react": "17.0.2", "react-dom": "17.0.2", "react-intl": "^6.3.2", - "react-router-dom": "5.3.4", + "react-router-dom": "6", "react-test-renderer": "17.0.2", "react-value": "0.2.0", "replace": "1.2.2", @@ -163,7 +163,6 @@ "@types/eslint": "^9.0.0", "@types/react": "17.0.83", "@types/react-dom": "17.0.25", - "@types/react-router": "5.1.20", "@types/unist": "3.0.3", "@typescript-eslint/eslint-plugin": "8.9.0", "@typescript-eslint/parser": "8.9.0", diff --git a/packages/components/buttons/link-button/package.json b/packages/components/buttons/link-button/package.json index d8011055a4..750df23650 100644 --- a/packages/components/buttons/link-button/package.json +++ b/packages/components/buttons/link-button/package.json @@ -34,11 +34,11 @@ "devDependencies": { "react": "17.0.2", "react-intl": "^6.3.2", - "react-router-dom": "5.3.4" + "react-router-dom": "6" }, "peerDependencies": { "react": "17.x", "react-intl": "6.x", - "react-router-dom": "5.x" + "react-router-dom": "6.x" } } diff --git a/packages/components/buttons/link-button/src/link-button.spec.js b/packages/components/buttons/link-button/src/link-button.spec.js index fd657ed9f9..6cf809eeff 100644 --- a/packages/components/buttons/link-button/src/link-button.spec.js +++ b/packages/components/buttons/link-button/src/link-button.spec.js @@ -5,6 +5,7 @@ import { fireEvent, waitFor, } from '../../../../../test/test-utils'; +import { Routes, Route } from 'react-router-dom'; import LinkButton from './link-button'; const createTestProps = (custom) => ({ @@ -38,10 +39,15 @@ describe('rendering', () => { expect(screen.getByLabelText('test-button')).toBeEnabled(); }); it('should navigate to link when clicked', async () => { - const { history } = render(); + render( + + } /> + Foo Bar Page} /> + + ); fireEvent.click(screen.getByLabelText('test-button')); await waitFor(() => { - expect(history.location.pathname).toBe('/foo/bar'); + expect(screen.getByText('Foo Bar Page')).toBeInTheDocument(); }); }); it('should pass aria attributes"', () => { @@ -52,10 +58,18 @@ describe('rendering', () => { ); }); it('should prevent the navigation when "disabled"', async () => { - const { history } = render(); + render( + + } /> + Foo Bar Page} /> + + ); fireEvent.click(screen.getByLabelText('test-button')); await waitFor(() => { - expect(history.location.pathname).toBe('/'); + expect(screen.getByLabelText('test-button')).toBeInTheDocument(); + }); + await waitFor(() => { + expect(screen.queryByText('Foo Bar Page')).not.toBeInTheDocument(); }); }); it('should render icon', () => { diff --git a/packages/components/buttons/link-button/src/link-button.tsx b/packages/components/buttons/link-button/src/link-button.tsx index ea75bb1177..6e8a4bfc2c 100644 --- a/packages/components/buttons/link-button/src/link-button.tsx +++ b/packages/components/buttons/link-button/src/link-button.tsx @@ -1,5 +1,3 @@ -import type { LocationDescriptor } from 'history'; - import { cloneElement, ReactElement } from 'react'; import { Link as ReactRouterLink } from 'react-router-dom'; import { css } from '@emotion/react'; @@ -12,6 +10,8 @@ import { import Inline from '@commercetools-uikit/spacings-inline'; import Text from '@commercetools-uikit/text'; +type LocationDescriptor = { pathname: string; search?: string; hash?: string }; + export type TLinkButtonProps = { /** * Should describe what the button is for. diff --git a/packages/components/buttons/secondary-button/package.json b/packages/components/buttons/secondary-button/package.json index 1f1c73cac3..ac86c49e4d 100644 --- a/packages/components/buttons/secondary-button/package.json +++ b/packages/components/buttons/secondary-button/package.json @@ -34,11 +34,11 @@ "devDependencies": { "react": "17.0.2", "react-intl": "^6.3.2", - "react-router-dom": "5.3.4" + "react-router-dom": "6" }, "peerDependencies": { "react": "17.x", "react-intl": "6.x", - "react-router-dom": "5.x" + "react-router-dom": "6.x" } } diff --git a/packages/components/buttons/secondary-button/src/secondary-button.spec.js b/packages/components/buttons/secondary-button/src/secondary-button.spec.js index 5022942341..928e9d57a5 100644 --- a/packages/components/buttons/secondary-button/src/secondary-button.spec.js +++ b/packages/components/buttons/secondary-button/src/secondary-button.spec.js @@ -1,4 +1,4 @@ -import { Link } from 'react-router-dom'; +import { Routes, Route, Link } from 'react-router-dom'; import { PlusBoldIcon } from '@commercetools-uikit/icons'; import { screen, @@ -95,12 +95,25 @@ describe('rendering', () => { }); describe('when using as', () => { it('should navigate to link when clicked', async () => { - const { history } = render( - + render( + + + } + /> + Foo Bar Page} /> + ); fireEvent.click(screen.getByLabelText('Add')); await waitFor(() => { - expect(history.location.pathname).toBe('/foo/bar'); + expect(screen.getByText('Foo Bar Page')).toBeInTheDocument(); }); }); }); diff --git a/packages/components/card/package.json b/packages/components/card/package.json index 070d2dd2e8..c852bfd055 100644 --- a/packages/components/card/package.json +++ b/packages/components/card/package.json @@ -26,15 +26,14 @@ "@commercetools-uikit/utils": "19.16.0", "@emotion/react": "^11.10.5", "@emotion/styled": "^11.10.5", - "@types/react-router-dom": "^5.3.3", "prop-types": "15.8.1" }, "devDependencies": { "react": "17.0.2", - "react-router-dom": "5.3.4" + "react-router-dom": "6" }, "peerDependencies": { "react": "17.x", - "react-router-dom": "5.x" + "react-router-dom": "6.x" } } diff --git a/packages/components/card/src/card.spec.tsx b/packages/components/card/src/card.spec.tsx index 8897e9e721..8a9f730207 100644 --- a/packages/components/card/src/card.spec.tsx +++ b/packages/components/card/src/card.spec.tsx @@ -1,6 +1,5 @@ import { screen, render, fireEvent } from '../../../../test/test-utils'; import Card from './card'; -import { BrowserRouter } from 'react-router-dom'; // Required for testing it('should render children', () => { render(Bread); @@ -34,11 +33,7 @@ it('should not call `onClick` when the card is disabled', () => { it('should render as a react-router `Link` when `to` prop is provided', () => { const content = 'Internal Link'; - render( - - {content} - - ); + render({content}); const link = screen.getByText(content).closest('a'); expect(link).toHaveAttribute('href', '/internal-link'); diff --git a/packages/components/card/src/card.tsx b/packages/components/card/src/card.tsx index 0e7eef0347..47de3c4489 100644 --- a/packages/components/card/src/card.tsx +++ b/packages/components/card/src/card.tsx @@ -3,8 +3,7 @@ import { css } from '@emotion/react'; import { designTokens } from '@commercetools-uikit/design-system'; import { filterDataAttributes, warning } from '@commercetools-uikit/utils'; import Inset from '@commercetools-uikit/spacings-inset'; -import { Link } from 'react-router-dom'; -import type { LocationDescriptor } from 'history'; +import { Link, LinkProps } from 'react-router-dom'; export type TCardProps = { /** @@ -34,7 +33,7 @@ export type TCardProps = { /** * The URL that the Card should point to. If provided, the Card will be rendered as an anchor element. */ - to?: string | LocationDescriptor; + to?: LinkProps['to']; /** * A flag to indicate if the Card points to an external source. */ diff --git a/packages/components/fields/async-creatable-select-field/src/async-creatable-select-field.visualroute.jsx b/packages/components/fields/async-creatable-select-field/src/async-creatable-select-field.visualroute.jsx index 1a0a3e2c95..02e43096f7 100644 --- a/packages/components/fields/async-creatable-select-field/src/async-creatable-select-field.visualroute.jsx +++ b/packages/components/fields/async-creatable-select-field/src/async-creatable-select-field.visualroute.jsx @@ -1,4 +1,4 @@ -import { Switch, Route } from 'react-router-dom'; +import { Routes, Route } from 'react-router-dom'; import { AsyncCreatableSelectField } from '@commercetools-frontend/ui-kit'; import { Suite, Spec } from '../../../../../test/percy'; @@ -126,10 +126,10 @@ const DefaultRoute = () => ( ); const InteractionRoute = () => ( - + ( + path="without-default-options/*" + element={ ( /> - )} + } /> - ( + path="/*" + element={ ( /> - )} + } /> - + ); export const component = () => ( - - - - + + } /> + } /> + ); diff --git a/packages/components/fields/async-select-field/src/async-select-field.visualroute.jsx b/packages/components/fields/async-select-field/src/async-select-field.visualroute.jsx index efa459b380..384353da7c 100644 --- a/packages/components/fields/async-select-field/src/async-select-field.visualroute.jsx +++ b/packages/components/fields/async-select-field/src/async-select-field.visualroute.jsx @@ -1,4 +1,4 @@ -import { Switch, Route } from 'react-router-dom'; +import { Routes, Route } from 'react-router-dom'; import { AsyncSelectField } from '@commercetools-frontend/ui-kit'; import { Suite, Spec } from '../../../../../test/percy'; @@ -126,10 +126,10 @@ const DefaultRoute = () => ( ); const InteractionRoute = () => ( - + ( + path="without-default-options/*" + element={ ( /> - )} + } /> ( + path="/*" + element={ ( /> - )} + } /> - + ); export const component = () => ( - - - - + + } /> + } /> + ); diff --git a/packages/components/icons/src/icons.visualroute.jsx b/packages/components/icons/src/icons.visualroute.jsx index 2011e5c122..b314e7fe0c 100644 --- a/packages/components/icons/src/icons.visualroute.jsx +++ b/packages/components/icons/src/icons.visualroute.jsx @@ -1,5 +1,5 @@ import styled from '@emotion/styled'; -import { Switch, Route } from 'react-router-dom'; +import { Routes, Route } from 'react-router-dom'; import { designTokens } from '@commercetools-uikit/design-system'; import * as icons from '@commercetools-uikit/icons'; import CustomIcon from '@commercetools-uikit/icons/custom-icon'; @@ -83,8 +83,9 @@ const renderIcon = (iconName, color, size) => { }; export const component = () => ( - - + + {colors.map((color) => (
  • @@ -106,10 +107,11 @@ export const component = () => ( {`${routePath}/custom-icon`}
  • -
    + } + /> {colors.map((color) => ( - - + {sizes.map((size) => ( ( ))} - + } + /> ))} - + {sizes.map((size) => ( @@ -151,8 +155,10 @@ export const component = () => ( ))} - - + } + /> + {leadingIconSizes.map((size) => ( @@ -202,8 +208,10 @@ export const component = () => ( - - + } + /> + @@ -246,6 +254,7 @@ export const component = () => ( - -
    + } + /> + ); diff --git a/packages/components/inputs/localized-rich-text-input/src/localized-rich-text-input.visualroute.jsx b/packages/components/inputs/localized-rich-text-input/src/localized-rich-text-input.visualroute.jsx index 39a2b7a698..03a7ece2d8 100644 --- a/packages/components/inputs/localized-rich-text-input/src/localized-rich-text-input.visualroute.jsx +++ b/packages/components/inputs/localized-rich-text-input/src/localized-rich-text-input.visualroute.jsx @@ -1,4 +1,4 @@ -import { Switch, Route } from 'react-router-dom'; +import { Routes, Route } from 'react-router-dom'; import { useState, useCallback, useRef, forwardRef } from 'react'; import { LocalizedRichTextInput, @@ -306,8 +306,8 @@ const DefaultRoute = () => ( ); export const component = () => ( - - - - + + } /> + } /> + ); diff --git a/packages/components/inputs/rich-text-input/src/rich-text-input.visualroute.jsx b/packages/components/inputs/rich-text-input/src/rich-text-input.visualroute.jsx index 5e00b151d6..8bd5a11f66 100644 --- a/packages/components/inputs/rich-text-input/src/rich-text-input.visualroute.jsx +++ b/packages/components/inputs/rich-text-input/src/rich-text-input.visualroute.jsx @@ -1,5 +1,5 @@ import { useState, useCallback, useRef } from 'react'; -import { Switch, Route } from 'react-router'; +import { Routes, Route } from 'react-router'; import { RichTextInput } from '@commercetools-frontend/ui-kit'; import { Suite, Spec } from '../../../../../test/percy'; @@ -165,8 +165,8 @@ const DefaultRoute = () => ( ); export const component = () => ( - - - - + + } /> + } /> + ); diff --git a/packages/components/inputs/select-input/src/select-input.visualroute.jsx b/packages/components/inputs/select-input/src/select-input.visualroute.jsx index b5fbb41fc3..491490e6eb 100644 --- a/packages/components/inputs/select-input/src/select-input.visualroute.jsx +++ b/packages/components/inputs/select-input/src/select-input.visualroute.jsx @@ -1,5 +1,5 @@ /* eslint-disable react/prop-types */ -import { Route, Switch } from 'react-router-dom'; +import { Route, Routes } from 'react-router-dom'; import { SelectInput } from '@commercetools-frontend/ui-kit'; import { Suite, Spec } from '../../../../../test/percy'; import { WorldIcon } from '../../../icons'; @@ -285,16 +285,16 @@ const OpenRouteWithOptionGroupsAndDivider = () => ( ); export const component = () => ( - - + + } /> } /> } /> - } /> - + } /> + ); diff --git a/packages/components/link/README.md b/packages/components/link/README.md index 0afa2ae9df..b1d65a480e 100644 --- a/packages/components/link/README.md +++ b/packages/components/link/README.md @@ -49,7 +49,7 @@ export default Example; | `children` | `ReactNode` | | | Value of the link.
    Required if `intlMessage` is not provided. | | `intlMessage` | `MessageDescriptor` | | | An `intl` message object that will be rendered with `FormattedMessage`.
    Required if `children` is not provided. | | `isExternal` | `boolean` | | `false` | A flag to indicate if the Link points to an external source. If `true`, a regular `` is rendered instead of the default `react-router`s `` | -| `to` | `union`
    Possible values:
    `string , LocationDescriptor` | ✅ | | The URL that the Link should point to. | +| `to` | `LinkProps['to']` | ✅ | | The relative URL that the Link should point to. | | `tone` | `union`
    Possible values:
    `'primary' , 'inverted', 'secondary'` | | `'primary'` | Color of the link | | `onClick` | `Function`
    [See signature.](#signature-onClick) | | | Handler when the link is clicked. | diff --git a/packages/components/link/package.json b/packages/components/link/package.json index 408e0a7f50..387c6475cb 100644 --- a/packages/components/link/package.json +++ b/packages/components/link/package.json @@ -27,19 +27,17 @@ "@commercetools-uikit/utils": "19.16.0", "@emotion/react": "^11.10.5", "@emotion/styled": "^11.10.5", - "@types/history": "^4.7.11", - "@types/react-router-dom": "^5.3.3", "history": "4.10.1", "prop-types": "15.8.1" }, "devDependencies": { "react": "17.0.2", "react-intl": "^6.3.2", - "react-router-dom": "5.3.4" + "react-router-dom": "6" }, "peerDependencies": { "react": "17.x", "react-intl": "6.x", - "react-router-dom": "5.x" + "react-router-dom": "6.x" } } diff --git a/packages/components/link/src/link.tsx b/packages/components/link/src/link.tsx index 540739440b..66fcc47aed 100644 --- a/packages/components/link/src/link.tsx +++ b/packages/components/link/src/link.tsx @@ -1,4 +1,3 @@ -import type { LocationDescriptor } from 'history'; import type { MessageDescriptor } from 'react-intl'; import { Children, @@ -7,7 +6,7 @@ import { type KeyboardEvent, } from 'react'; import styled from '@emotion/styled'; -import { Link as ReactRouterLink } from 'react-router-dom'; +import { LinkProps, Link as ReactRouterLink } from 'react-router-dom'; import { css } from '@emotion/react'; import { FormattedMessage } from 'react-intl'; import { designTokens } from '@commercetools-uikit/design-system'; @@ -36,9 +35,9 @@ export type TLinkProps = { */ isExternal: boolean; /** - * The URL that the Link should point to. + * The relative URL that the Link should point to. */ - to: string | LocationDescriptor; + to: LinkProps['to']; /** * Color of the link */ diff --git a/packages/components/primary-action-dropdown/src/primary-action-dropdown.visualroute.jsx b/packages/components/primary-action-dropdown/src/primary-action-dropdown.visualroute.jsx index 2e5696e872..d385348963 100644 --- a/packages/components/primary-action-dropdown/src/primary-action-dropdown.visualroute.jsx +++ b/packages/components/primary-action-dropdown/src/primary-action-dropdown.visualroute.jsx @@ -1,4 +1,4 @@ -import { Route, Switch } from 'react-router-dom'; +import { Route, Routes } from 'react-router-dom'; import { PrimaryActionDropdown, PrimaryActionDropdownOption, @@ -62,8 +62,8 @@ const DefaultRoute = () => ( ); export const component = () => ( - - - - + + } /> + } /> + ); diff --git a/packages/components/tag/README.md b/packages/components/tag/README.md index bbd68eceaa..3c7c3079a9 100644 --- a/packages/components/tag/README.md +++ b/packages/components/tag/README.md @@ -59,7 +59,7 @@ export default Example; | ---------------------- | ----------------------------------------------------------------------------------------------------------- | :------: | ----------- | ------------------------------------------------------------------------------------- | | `type` | `union`
    Possible values:
    `'normal' , 'warning'` | | | Indicates color scheme of the tag. @deprecated use `tone` instead | | `styles` | `Record` | | | Styles object that is spread into the tag body. | -| `to` | `union`
    Possible values:
    `string , LocationDescriptor` | | | Link of the tag when not disabled | +| `to` | `LinkProps['to']` | | | Link of the tag when not disabled | | `isDisabled` | `boolean` | | `false` | Disable the tag element along with the option to remove it. | | `isDraggable` | `boolean` | | `false` | Adds the draggable icon on the left side. | | `onRemove` | `Function`
    [See signature.](#signature-onRemove) | | | Called when remove button is clicked. | diff --git a/packages/components/tag/package.json b/packages/components/tag/package.json index 850524384f..2376565253 100644 --- a/packages/components/tag/package.json +++ b/packages/components/tag/package.json @@ -35,10 +35,10 @@ }, "devDependencies": { "react": "17.0.2", - "react-router-dom": "5.3.4" + "react-router-dom": "6" }, "peerDependencies": { "react": "17.x", - "react-router-dom": "5.x" + "react-router-dom": "6.x" } } diff --git a/packages/components/tag/src/tag.spec.js b/packages/components/tag/src/tag.spec.js index 82de76b265..13ebc03841 100644 --- a/packages/components/tag/src/tag.spec.js +++ b/packages/components/tag/src/tag.spec.js @@ -1,4 +1,5 @@ import { screen, render } from '../../../../test/test-utils'; +import { Route, Routes, useNavigate } from 'react-router-dom'; import Tag from './tag'; it('should render text as children', () => { @@ -107,31 +108,62 @@ describe('when draggable', () => { describe('when `to` is set', () => { it('should redirect when clicked', () => { - const { history } = render(Bread); - screen.getByText('Bread').click(); + render( + + Bread} /> + Redirected to Foo} /> + , + { route: '/' } + ); - expect(history.location.pathname).toBe('/foo'); + screen.getByText('Bread').click(); + expect(screen.getByText('Redirected to Foo')).toBeInTheDocument(); // Assert on UI }); it('should still call onClick when clicked', () => { const onClick = jest.fn(); - const { history } = render( - - Bread - + + render( + + + Bread + + } + /> + Redirected to Foo} /> + , + { route: '/' } ); + screen.getByText('Bread').click(); - expect(onClick).toHaveBeenCalled(); - expect(history.location.pathname).toBe('/foo'); + expect(onClick).toHaveBeenCalled(); // Assert click handler was called + expect(screen.getByText('Redirected to Foo')).toBeInTheDocument(); // Assert redirect }); it('should redirect on link click if text children proceed it', () => { - const { history } = render( - - Bread - Peanut Butter - history.push('/honey')}>Honey - + const TagWithNavigation = () => { + const navigate = useNavigate(); + + return navigate('/honey')}>Honey; + }; + render( + + + Bread + Peanut Butter + + + } + /> + Redirected to Honey} /> + , + { route: '/' } ); expect(screen.getByText('Bread')).toBeInTheDocument(); @@ -139,38 +171,56 @@ describe('when `to` is set', () => { expect(screen.getByText('Honey')).toBeInTheDocument(); screen.getByText('Honey').click(); - expect(history.location.pathname).toBe('/honey'); + expect(screen.getByText('Redirected to Honey')).toBeInTheDocument(); // Assert redirect }); it('should not redirect when removed', () => { const onRemove = jest.fn(); - const { history } = render( - - Bread - + + render( + + + Bread + + } + /> + Redirected to Foo} /> + , + { route: '/' } ); screen.getByLabelText('Remove').click(); - // ensure "onRemove" is stil called + // Ensure "onRemove" is still called expect(onRemove).toHaveBeenCalled(); - // ensure the pathname is not "/foo", otherwise a redirect would have - // happened - expect(history.location.pathname).toBe('/'); + // Ensure no redirect occurred by checking the current content + expect(screen.queryByText('Redirected to Foo')).not.toBeInTheDocument(); }); it('should not redirect when disabled', () => { - const { history } = render( - - Bread - + render( + + + Bread + + } + /> + Redirected to Foo} /> + , + { route: '/' } ); screen.getByText('Bread').click(); - // ensure the pathname is not "/foo", otherwise a redirect would have + // ensure there is not text with `Redirected to Foo`, otherwise a redirect would have // happened - expect(history.location.pathname).toBe('/'); + expect(screen.queryByText('Redirected to Foo')).not.toBeInTheDocument(); }); }); diff --git a/packages/components/tag/src/tag.tsx b/packages/components/tag/src/tag.tsx index 68ab30f95a..b1eb8530d9 100644 --- a/packages/components/tag/src/tag.tsx +++ b/packages/components/tag/src/tag.tsx @@ -1,7 +1,6 @@ -import type { LocationDescriptor } from 'history'; import { ReactNode, MouseEvent, KeyboardEvent, ElementType } from 'react'; import { css, type SerializedStyles } from '@emotion/react'; -import { Link } from 'react-router-dom'; +import { Link, LinkProps } from 'react-router-dom'; import { designTokens } from '@commercetools-uikit/design-system'; import Constraints from '@commercetools-uikit/constraints'; import AccessibleButton from '@commercetools-uikit/accessible-button'; @@ -22,7 +21,7 @@ export type TTagProps = { /** * Link of the tag when not disabled */ - to?: string | LocationDescriptor; + to?: LinkProps['to']; /** * Disable the tag element along with the option to remove it. */ diff --git a/presets/buttons/package.json b/presets/buttons/package.json index 594c07dca4..16ef2f0345 100644 --- a/presets/buttons/package.json +++ b/presets/buttons/package.json @@ -33,11 +33,11 @@ "devDependencies": { "react": "17.0.2", "react-intl": "^6.3.2", - "react-router-dom": "5.3.4" + "react-router-dom": "6" }, "peerDependencies": { "react": "17.x", "react-intl": "6.x", - "react-router-dom": "5.x" + "react-router-dom": "6.x" } } diff --git a/presets/fields/package.json b/presets/fields/package.json index 49ca433c2a..af8d15ea47 100644 --- a/presets/fields/package.json +++ b/presets/fields/package.json @@ -42,11 +42,11 @@ "devDependencies": { "react": "17.0.2", "react-intl": "^6.3.2", - "react-router-dom": "5.3.4" + "react-router-dom": "6" }, "peerDependencies": { "react": "17.x", "react-intl": "6.x", - "react-router-dom": "5.x" + "react-router-dom": "6.x" } } diff --git a/presets/inputs/package.json b/presets/inputs/package.json index 0b7e7df9a2..182ae31434 100644 --- a/presets/inputs/package.json +++ b/presets/inputs/package.json @@ -49,11 +49,11 @@ "devDependencies": { "react": "17.0.2", "react-intl": "^6.3.2", - "react-router-dom": "5.3.4" + "react-router-dom": "6" }, "peerDependencies": { "react": "17.x", "react-intl": "6.x", - "react-router-dom": "5.x" + "react-router-dom": "6.x" } } diff --git a/presets/ui-kit/package.json b/presets/ui-kit/package.json index 22436fa52e..237433be05 100644 --- a/presets/ui-kit/package.json +++ b/presets/ui-kit/package.json @@ -68,13 +68,13 @@ "moment-timezone": "0.5.46", "react": "17.0.2", "react-intl": "^6.3.2", - "react-router-dom": "5.3.4" + "react-router-dom": "6" }, "peerDependencies": { "moment": "2.x", "moment-timezone": "0.5.x", "react": "17.x", "react-intl": "6.x", - "react-router-dom": "5.x" + "react-router-dom": "6.x" } } diff --git a/test/setup-tests.js b/test/setup-tests.js index d323c2abfc..def72c1aa3 100644 --- a/test/setup-tests.js +++ b/test/setup-tests.js @@ -35,6 +35,7 @@ Object.defineProperty(window, 'TextDecoder', { const silenceConsoleWarnings = []; const notThrowWarnings = [ /"children" property of "Stamp" component has been deprecated/, + /React Router Future Flag Warning/, ]; const shouldSilenceWarnings = (...messages) => diff --git a/test/test-utils.js b/test/test-utils.js index 45c8d37342..c774459a70 100644 --- a/test/test-utils.js +++ b/test/test-utils.js @@ -2,8 +2,7 @@ import { render } from '@testing-library/react'; import { IntlProvider } from 'react-intl'; -import { Router } from 'react-router-dom'; -import { createMemoryHistory } from 'history'; +import { MemoryRouter } from 'react-router-dom'; const getMessagesForLocale = (locale) => { switch (locale) { @@ -24,26 +23,17 @@ const getMessagesForLocale = (locale) => { const customRender = ( node, - { - locale = 'en', - route = '/', - history = createMemoryHistory({ initialEntries: [route] }), - ...rtlOptions - } = {} + { locale = 'en', route = '/', ...rtlOptions } = {} ) => ({ ...render( - {node} + {node} , rtlOptions ), - // adding `history` to the returned utilities to allow us - // to reference it in our tests (just try to avoid using - // this to test implementation details). - history, }); -// re-export everything +// Re-export everything export { act, fireEvent, @@ -53,5 +43,5 @@ export { within, } from '@testing-library/react'; -// override render method +// Override render method export { customRender as render }; diff --git a/visual-testing-app/package.json b/visual-testing-app/package.json index a78a74e896..778bf618a4 100644 --- a/visual-testing-app/package.json +++ b/visual-testing-app/package.json @@ -20,8 +20,8 @@ "react": "17.0.2", "react-dom": "17.0.2", "react-intl": "^6.3.2", - "react-router": "5.3.4", - "react-router-dom": "5.3.4" + "react-router": "6", + "react-router-dom": "6" }, "devDependencies": { "@vitejs/plugin-react": "4.3.2", diff --git a/visual-testing-app/src/App.tsx b/visual-testing-app/src/App.tsx index 8fb8f4f1f1..da2fdfea1e 100644 --- a/visual-testing-app/src/App.tsx +++ b/visual-testing-app/src/App.tsx @@ -1,6 +1,6 @@ /// import './globals.css'; -import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'; +import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; import { ThemeProvider } from '@commercetools-uikit/design-system'; interface TRouteComponent { @@ -46,11 +46,10 @@ const App = () => { <> - + ( + element={

    Visual Testing App

      @@ -61,25 +60,26 @@ const App = () => { ))}
    - )} + } /> {allSortedComponents.map((Component) => ( } + element={} /> ))} ( + path="*" + element={
    - )} + } /> - + ); diff --git a/yarn.lock b/yarn.lock index 2c5e02e2cf..31fd90e528 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1952,7 +1952,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.12.0, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.14.8, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.17.8, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.22.5, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.7.7, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": +"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.12.0, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.14.8, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.17.8, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.22.5, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.7.7, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": version: 7.25.0 resolution: "@babel/runtime@npm:7.25.0" dependencies: @@ -2435,13 +2435,13 @@ __metadata: moment-timezone: 0.5.46 react: 17.0.2 react-intl: ^6.3.2 - react-router-dom: 5.3.4 + react-router-dom: 6 peerDependencies: moment: 2.x moment-timezone: 0.5.x react: 17.x react-intl: 6.x - react-router-dom: 5.x + react-router-dom: 6.x languageName: unknown linkType: soft @@ -2712,11 +2712,11 @@ __metadata: "@commercetools-uikit/secondary-icon-button": 19.16.0 react: 17.0.2 react-intl: ^6.3.2 - react-router-dom: 5.3.4 + react-router-dom: 6 peerDependencies: react: 17.x react-intl: 6.x - react-router-dom: 5.x + react-router-dom: 6.x languageName: unknown linkType: soft @@ -2777,13 +2777,12 @@ __metadata: "@commercetools-uikit/utils": 19.16.0 "@emotion/react": ^11.10.5 "@emotion/styled": ^11.10.5 - "@types/react-router-dom": ^5.3.3 prop-types: 15.8.1 react: 17.0.2 - react-router-dom: 5.3.4 + react-router-dom: 6 peerDependencies: react: 17.x - react-router-dom: 5.x + react-router-dom: 6.x languageName: unknown linkType: soft @@ -3315,11 +3314,11 @@ __metadata: "@commercetools-uikit/time-field": 19.16.0 react: 17.0.2 react-intl: ^6.3.2 - react-router-dom: 5.3.4 + react-router-dom: 6 peerDependencies: react: 17.x react-intl: 6.x - react-router-dom: 5.x + react-router-dom: 6.x languageName: unknown linkType: soft @@ -3513,11 +3512,11 @@ __metadata: "@commercetools-uikit/toggle-input": 19.16.0 react: 17.0.2 react-intl: ^6.3.2 - react-router-dom: 5.3.4 + react-router-dom: 6 peerDependencies: react: 17.x react-intl: 6.x - react-router-dom: 5.x + react-router-dom: 6.x languageName: unknown linkType: soft @@ -3558,11 +3557,11 @@ __metadata: prop-types: 15.8.1 react: 17.0.2 react-intl: ^6.3.2 - react-router-dom: 5.3.4 + react-router-dom: 6 peerDependencies: react: 17.x react-intl: 6.x - react-router-dom: 5.x + react-router-dom: 6.x languageName: unknown linkType: soft @@ -3578,17 +3577,15 @@ __metadata: "@commercetools-uikit/utils": 19.16.0 "@emotion/react": ^11.10.5 "@emotion/styled": ^11.10.5 - "@types/history": ^4.7.11 - "@types/react-router-dom": ^5.3.3 history: 4.10.1 prop-types: 15.8.1 react: 17.0.2 react-intl: ^6.3.2 - react-router-dom: 5.3.4 + react-router-dom: 6 peerDependencies: react: 17.x react-intl: 6.x - react-router-dom: 5.x + react-router-dom: 6.x languageName: unknown linkType: soft @@ -4367,11 +4364,11 @@ __metadata: prop-types: 15.8.1 react: 17.0.2 react-intl: ^6.3.2 - react-router-dom: 5.3.4 + react-router-dom: 6 peerDependencies: react: 17.x react-intl: 6.x - react-router-dom: 5.x + react-router-dom: 6.x languageName: unknown linkType: soft @@ -4622,10 +4619,10 @@ __metadata: prop-types: 15.8.1 react: 17.0.2 react-intl: ^6.3.2 - react-router-dom: 5.3.4 + react-router-dom: 6 peerDependencies: react: 17.x - react-router-dom: 5.x + react-router-dom: 6.x languageName: unknown linkType: soft @@ -7255,6 +7252,13 @@ __metadata: languageName: node linkType: hard +"@remix-run/router@npm:1.21.0": + version: 1.21.0 + resolution: "@remix-run/router@npm:1.21.0" + checksum: d9477a7772053ad0ffcf03385cfb1a54e56f8a56d1f9f5062de3b1dfcbd019dd73282a00a5a72aa55c120771110982448c165c1405d64540aaef13051a8e45cc + languageName: node + linkType: hard + "@rollup/plugin-alias@npm:^3.1.1": version: 3.1.9 resolution: "@rollup/plugin-alias@npm:3.1.9" @@ -8743,13 +8747,6 @@ __metadata: languageName: node linkType: hard -"@types/history@npm:^4.7.11": - version: 4.7.11 - resolution: "@types/history@npm:4.7.11" - checksum: c92e2ba407dcab0581a9afdf98f533aa41b61a71133420a6d92b1ca9839f741ab1f9395b17454ba5b88cb86020b70b22d74a1950ccfbdfd9beeaa5459fdc3464 - languageName: node - linkType: hard - "@types/hoist-non-react-statics@npm:^3.3.0, @types/hoist-non-react-statics@npm:^3.3.1": version: 3.3.5 resolution: "@types/hoist-non-react-statics@npm:3.3.5" @@ -9033,27 +9030,6 @@ __metadata: languageName: node linkType: hard -"@types/react-router-dom@npm:^5.3.3": - version: 5.3.3 - resolution: "@types/react-router-dom@npm:5.3.3" - dependencies: - "@types/history": ^4.7.11 - "@types/react": "*" - "@types/react-router": "*" - checksum: 28c4ea48909803c414bf5a08502acbb8ba414669b4b43bb51297c05fe5addc4df0b8fd00e0a9d1e3535ec4073ef38aaafac2c4a2b95b787167d113bc059beff3 - languageName: node - linkType: hard - -"@types/react-router@npm:5.1.20": - version: 5.1.20 - resolution: "@types/react-router@npm:5.1.20" - dependencies: - "@types/history": ^4.7.11 - "@types/react": "*" - checksum: 128764143473a5e9457ddc715436b5d49814b1c214dde48939b9bef23f0e77f52ffcdfa97eb8d3cc27e2c229869c0cdd90f637d887b62f2c9f065a87d6425419 - languageName: node - linkType: hard - "@types/react-transition-group@npm:^4.4.0": version: 4.4.11 resolution: "@types/react-transition-group@npm:4.4.11" @@ -15096,7 +15072,7 @@ __metadata: languageName: node linkType: hard -"history@npm:4.10.1, history@npm:^4.9.0": +"history@npm:4.10.1": version: 4.10.1 resolution: "history@npm:4.10.1" dependencies: @@ -15110,7 +15086,7 @@ __metadata: languageName: node linkType: hard -"hoist-non-react-statics@npm:^3.1.0, hoist-non-react-statics@npm:^3.3.0, hoist-non-react-statics@npm:^3.3.1, hoist-non-react-statics@npm:^3.3.2": +"hoist-non-react-statics@npm:^3.3.0, hoist-non-react-statics@npm:^3.3.1, hoist-non-react-statics@npm:^3.3.2": version: 3.3.2 resolution: "hoist-non-react-statics@npm:3.3.2" dependencies: @@ -16128,13 +16104,6 @@ __metadata: languageName: node linkType: hard -"isarray@npm:0.0.1": - version: 0.0.1 - resolution: "isarray@npm:0.0.1" - checksum: 49191f1425681df4a18c2f0f93db3adb85573bcdd6a4482539d98eac9e705d8961317b01175627e860516a2fc45f8f9302db26e5a380a97a520e272e2a40a8d4 - languageName: node - linkType: hard - "isarray@npm:^2.0.5": version: 2.0.5 resolution: "isarray@npm:2.0.5" @@ -17570,7 +17539,7 @@ __metadata: languageName: node linkType: hard -"loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0, loose-envify@npm:^1.2.0, loose-envify@npm:^1.3.1, loose-envify@npm:^1.4.0": +"loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0, loose-envify@npm:^1.2.0, loose-envify@npm:^1.4.0": version: 1.4.0 resolution: "loose-envify@npm:1.4.0" dependencies: @@ -19758,15 +19727,6 @@ __metadata: languageName: node linkType: hard -"path-to-regexp@npm:^1.7.0": - version: 1.8.0 - resolution: "path-to-regexp@npm:1.8.0" - dependencies: - isarray: 0.0.1 - checksum: 709f6f083c0552514ef4780cb2e7e4cf49b0cc89a97439f2b7cc69a608982b7690fb5d1720a7473a59806508fc2dae0be751ba49f495ecf89fd8fbc62abccbcd - languageName: node - linkType: hard - "path-to-regexp@npm:^6.3.0": version: 6.3.0 resolution: "path-to-regexp@npm:6.3.0" @@ -20632,7 +20592,7 @@ __metadata: languageName: node linkType: hard -"react-is@npm:^16.13.1, react-is@npm:^16.6.0, react-is@npm:^16.7.0": +"react-is@npm:^16.13.1, react-is@npm:^16.7.0": version: 16.13.1 resolution: "react-is@npm:16.13.1" checksum: f7a19ac3496de32ca9ae12aa030f00f14a3d45374f1ceca0af707c831b2a6098ef0d6bdae51bd437b0a306d7f01d4677fcc8de7c0d331eb47ad0f46130e53c5f @@ -20702,39 +20662,27 @@ __metadata: languageName: node linkType: hard -"react-router-dom@npm:5.3.4": - version: 5.3.4 - resolution: "react-router-dom@npm:5.3.4" +"react-router-dom@npm:6": + version: 6.28.0 + resolution: "react-router-dom@npm:6.28.0" dependencies: - "@babel/runtime": ^7.12.13 - history: ^4.9.0 - loose-envify: ^1.3.1 - prop-types: ^15.6.2 - react-router: 5.3.4 - tiny-invariant: ^1.0.2 - tiny-warning: ^1.0.0 + "@remix-run/router": 1.21.0 + react-router: 6.28.0 peerDependencies: - react: ">=15" - checksum: b86a6f2f5222f041e38adf4e4b32c7643d6735a1a915ef25855b2db285fd059d72ba8d62e5bcd5d822b8ef9520a80453209e55077f5a90d0f72e908979b8f535 + react: ">=16.8" + react-dom: ">=16.8" + checksum: 0cf4658a92bc66f50ec9d8518c36aa5a402bcadce71fb624ed6f900d73a29ea87ff904a4f2c42279107e75e80cc08c6192563fadcc5d4e642e6d476e38e83b21 languageName: node linkType: hard -"react-router@npm:5.3.4": - version: 5.3.4 - resolution: "react-router@npm:5.3.4" +"react-router@npm:6, react-router@npm:6.28.0": + version: 6.28.0 + resolution: "react-router@npm:6.28.0" dependencies: - "@babel/runtime": ^7.12.13 - history: ^4.9.0 - hoist-non-react-statics: ^3.1.0 - loose-envify: ^1.3.1 - path-to-regexp: ^1.7.0 - prop-types: ^15.6.2 - react-is: ^16.6.0 - tiny-invariant: ^1.0.2 - tiny-warning: ^1.0.0 + "@remix-run/router": 1.21.0 peerDependencies: - react: ">=15" - checksum: 892d4e274a23bf4f39abc2efca54472fb646d3aed4b584020cf49654d2f50d09a2bacebe7c92b4ec7cb8925077376dfcd0664bad6442a73604397cefec9f01f9 + react: ">=16.8" + checksum: 23246ca957b5c2bc8d6f9a81fee2df2ce4fc3feca3ec27c2fd85999568fc1299a4e8273e4ab70b6f3acd43a1fb45e0c93cb01ef77e68c9f9e1f7e4f42a1419ea languageName: node linkType: hard @@ -23644,7 +23592,7 @@ __metadata: react: 17.0.2 react-dom: 17.0.2 react-intl: ^6.3.2 - react-router-dom: 5.3.4 + react-router-dom: 6 react-test-renderer: 17.0.2 react-value: 0.2.0 replace: 1.2.2 @@ -24311,8 +24259,8 @@ __metadata: react: 17.0.2 react-dom: 17.0.2 react-intl: ^6.3.2 - react-router: 5.3.4 - react-router-dom: 5.3.4 + react-router: 6 + react-router-dom: 6 vite: 5.4.9 languageName: unknown linkType: soft