Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .changeset/sixty-brooms-study.md
Original file line number Diff line number Diff line change
@@ -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 <Link to> 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
<Link to={`${match.url}/me`}>My Profile</Link>
```

```jsx
// v6: directly passed string is automatically interpreted as relative path
<Link to="me">My Profile</Link>
```
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,4 @@ const primary = designTokens.colorPrimary;
```

> Please look at the [`design-tokens.ts`](https://github.com/commercetools/ui-kit/blob/main/design-system/src/design-tokens.ts) itself to inspect which variables are available.
> test
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand Down
4 changes: 2 additions & 2 deletions packages/components/buttons/link-button/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
22 changes: 18 additions & 4 deletions packages/components/buttons/link-button/src/link-button.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) => ({
Expand Down Expand Up @@ -38,10 +39,15 @@ describe('rendering', () => {
expect(screen.getByLabelText('test-button')).toBeEnabled();
});
it('should navigate to link when clicked', async () => {
const { history } = render(<LinkButton {...props} />);
render(
<Routes>
<Route path="/" element={<LinkButton {...props} />} />
<Route path="/foo/bar" element={<div>Foo Bar Page</div>} />
</Routes>
);
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"', () => {
Expand All @@ -52,10 +58,18 @@ describe('rendering', () => {
);
});
it('should prevent the navigation when "disabled"', async () => {
const { history } = render(<LinkButton {...props} isDisabled={true} />);
render(
<Routes>
<Route path="/" element={<LinkButton {...props} isDisabled={true} />} />
<Route path="/foo/bar" element={<div>Foo Bar Page</div>} />
</Routes>
);
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', () => {
Expand Down
4 changes: 2 additions & 2 deletions packages/components/buttons/link-button/src/link-button.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions packages/components/buttons/secondary-button/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -95,12 +95,25 @@ describe('rendering', () => {
});
describe('when using as', () => {
it('should navigate to link when clicked', async () => {
const { history } = render(
<SecondaryButton {...props} onClick={null} as={Link} to="/foo/bar" />
render(
<Routes>
<Route
path="/"
element={
<SecondaryButton
{...props}
onClick={null}
as={Link}
to="/foo/bar"
/>
}
/>
<Route path="/foo/bar" element={<div>Foo Bar Page</div>} />
</Routes>
);
fireEvent.click(screen.getByLabelText('Add'));
await waitFor(() => {
expect(history.location.pathname).toBe('/foo/bar');
expect(screen.getByText('Foo Bar Page')).toBeInTheDocument();
});
});
});
Expand Down
5 changes: 2 additions & 3 deletions packages/components/card/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
7 changes: 1 addition & 6 deletions packages/components/card/src/card.spec.tsx
Original file line number Diff line number Diff line change
@@ -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 <Link>

it('should render children', () => {
render(<Card>Bread</Card>);
Expand Down Expand Up @@ -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(
<BrowserRouter>
<Card to="/internal-link">{content}</Card>
</BrowserRouter>
);
render(<Card to="/internal-link">{content}</Card>);

const link = screen.getByText(content).closest('a');
expect(link).toHaveAttribute('href', '/internal-link');
Expand Down
5 changes: 2 additions & 3 deletions packages/components/card/src/card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
/**
Expand Down Expand Up @@ -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.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -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';

Expand Down Expand Up @@ -126,7 +126,7 @@ const DefaultRoute = () => (
);

const InteractionRoute = () => (
<Switch>
<Routes>
<Route
path={`${routePath}/interaction/without-default-options`}
render={() => (
Expand Down Expand Up @@ -163,12 +163,12 @@ const InteractionRoute = () => (
</Suite>
)}
/>
</Switch>
</Routes>
);

export const component = () => (
<Switch>
<Routes>
<Route path={`${routePath}/interaction`} component={InteractionRoute} />
<Route path={routePath} component={DefaultRoute} />
</Switch>
</Routes>
);
Original file line number Diff line number Diff line change
@@ -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';

Expand Down Expand Up @@ -126,7 +126,7 @@ const DefaultRoute = () => (
);

const InteractionRoute = () => (
<Switch>
<Routes>
<Route
path={`${routePath}/interaction/without-default-options`}
render={() => (
Expand Down Expand Up @@ -163,12 +163,12 @@ const InteractionRoute = () => (
</Suite>
)}
/>
</Switch>
</Routes>
);

export const component = () => (
<Switch>
<Routes>
<Route path={`${routePath}/interaction`} component={InteractionRoute} />
<Route exact path={routePath} component={DefaultRoute} />
</Switch>
</Routes>
);
6 changes: 3 additions & 3 deletions packages/components/icons/src/icons.visualroute.jsx
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -83,7 +83,7 @@ const renderIcon = (iconName, color, size) => {
};

export const component = () => (
<Switch>
<Routes>
<Route path={routePath} exact>
<ul>
{colors.map((color) => (
Expand Down Expand Up @@ -247,5 +247,5 @@ export const component = () => (
</Spec>
</Suite>
</Route>
</Switch>
</Routes>
);
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -306,8 +306,8 @@ const DefaultRoute = () => (
);

export const component = () => (
<Switch>
<Routes>
<Route path={`${routePath}/interactive`} component={InteractiveRoute} />
<Route path={routePath} component={DefaultRoute} />
</Switch>
</Routes>
);
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -285,7 +285,7 @@ const OpenRouteWithOptionGroupsAndDivider = () => (
);

export const component = () => (
<Switch>
<Routes>
<Route path={`${routePath}/open`} component={OpenRoute} />
<Route
path={`${routePath}/open-with-option-groups`}
Expand All @@ -296,5 +296,5 @@ export const component = () => (
component={OpenRouteWithOptionGroupsAndDivider}
/>
<Route path={routePath} render={() => <DefaultRoute />} />
</Switch>
</Routes>
);
2 changes: 1 addition & 1 deletion packages/components/link/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export default Example;
| `children` | `ReactNode` | | | Value of the link.&#xA;<br />&#xA;Required if `intlMessage` is not provided. |
| `intlMessage` | `MessageDescriptor` | | | An `intl` message object that will be rendered with `FormattedMessage`.&#xA;<br />&#xA;Required if `children` is not provided. |
| `isExternal` | `boolean` | | `false` | A flag to indicate if the Link points to an external source.&#xA;<bt />&#xA;If `true`, a regular `<a>` is rendered instead of the default `react-router`s `<Link />` |
| `to` | `union`<br/>Possible values:<br/>`string , LocationDescriptor` | ✅ | | The URL that the Link should point to. |
| `to` | `LinkProps['to']` | ✅ | | The relative URL that the Link should point to. |
| `tone` | `union`<br/>Possible values:<br/>`'primary' , 'inverted', 'secondary'` | | `'primary'` | Color of the link |
| `onClick` | `Function`<br/>[See signature.](#signature-onClick) | | | Handler when the link is clicked. |

Expand Down
6 changes: 2 additions & 4 deletions packages/components/link/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
Loading
Loading