Skip to content
Merged
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
332 changes: 332 additions & 0 deletions documentation/guides/migrating-from-v3-to-v4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,332 @@
# Migrating from v3 to v4

Polaris v4.0.0 removes most deprecated features introduced in v3.x.x releases. If you've been fixing deprecations in minor versions as they were introduced you shouldn't have much work to do. This file describes all breaking changes that require you to update your code.

## Table of contents

- [Testing](#polaris-testing)
- [Component API Changes](#polaris-component-api-changes)
- [AppProvider](#polaris-appprovider)
- [Autocomplete](#polaris-autocomplete)
- [Card](#polaris-card)
- [ChoiceList](#polaris-choicelist)
- [Icon](#polaris-icon)
- [Modal](#polaris-modal)
- [Navigation](#polaris-navigation)
- [Select](#polaris-select)
- [Tabs](#polaris-tabs)
- [Removed Exports](#polaris-removed-exports)
- [WithContext](#polaris-withcontext)
- [WithRef](#polaris-withref)
- [LinkLikeComponent](#polaris-linklikecomponent)
- [Dependencies](#polaris-dependencies)
- [TypeScript](#polaris-typescript)
- [CDN Usage](#polaris-cdn)

## Testing <a name="polaris-testing"></a>

We’ve migrated to [React’s new context API](https://reactjs.org/docs/context.html) while restructuring Polaris React’s entire context structure. We now expose all our internal contexts required for testing within a single `PolarisTestProvider` component.

**Note:** These examples use [Enzyme](https://airbnb.io/enzyme/). Other testing libraries can also be used, as shown in [these examples](https://github.com/Shopify/polaris-react/tree/master/examples).

In v3, you could hook into Polaris React's legacy contexts using `createPolarisContext` and `polarisContextTypes`.

```jsx
// old
import {mount} from 'enzyme';
import {createPolarisContext, polarisContextTypes} from '@shopify/polaris';

export function mountWithAppProvider(node) {
return mount(node, {
context: createPolarisContext(),
childContextTypes: polarisContextTypes,
});
}
```

In v4 you should to wrap your code in the `PolarisTestProvider` which
will provide all required contexts.

```jsx
// new
import {mount} from 'enzyme';
import {PolarisTestProvider} from '@shopify/polaris';
import translations from '../../locales/en.json';

export function mountWithPolaris(node, context = {}) {
return mount(node, {
wrappingComponent: PolarisTestProvider,
wrappingComponentProps: {i18n: translations, ...context},
});
}
```

## Component API changes <a name="polaris-component-api-changes"></a>

### AppProvider <a name="polaris-appprovider"></a>

Polaris now supports multiple languages and ships with [many translations](https://github.com/Shopify/polaris-react/blob/master/locales) to support internationalization. The `i18n` prop is now required to specify the translations you wish to use.

```jsx
// old
<AppProvider />

// new
import translations from '@shopify/polaris/locales/en.json';

<AppProvider i18n={translations}>
```

### Autocomplete <a name="polaris-autocomplete"></a>

The `Autocomplete.ComboBox.TextField` and `Autocomplete.ComboBox.OptionList` subcomponents have been removed. Use `Autocomplete.TextField` and `OptionList` instead.

```jsx
// old
<Autocomplete.ComboBox.TextField label="Example" />
<Autocomplete.ComboBox.OptionList onChange={() => {}} selected={[]} />

// new
<Autocomplete.TextField label="Example" />
<OptionList onChange={() => {}} selected={[]} />
```

### Card <a name="polaris-card"></a>

The `secondaryFooterAction` prop has been removed. Pass an array of actions into `secondaryFooterActions` instead.

```jsx
// old
<Card secondaryFooterAction={{content: 'Dismiss'}}>Polaris</Card>

// new
<Card secondaryFooterActions={[{content: 'Dismiss'}]}>Polaris</Card>
```

### ChoiceList <a name="polaris-choicelist"></a>

The `title` prop is now required. If you want the title to be visually hidden set a `title` for screen-readers and set `titleHidden` to hide it from view.

```jsx
// old
<ChoiceList
choices={[
{label: 'Choice One', value: 'one'},
{label: 'Choice Two', value: 'two'},
]}
selected={['one']}
/>


// new
<ChoiceList
title={'Meaningful title'}
titleHidden
choices={[
{label: 'Choice One', value: 'one'},
{label: 'Choice Two', value: 'two'},
]}
selected={['one']}
/>
```

### Icon <a name="polaris-icon"></a>

The `source` prop no longer accepts a string that refers to a bundled icon name. Pass in a React component, such as the icons from `@shopify/polaris-icons` or icons processed through [SVGR](https://www.smooth-code.com/open-source/svgr/), into the `source` prop instead.

Applications using sewing-kit must update to at least version v0.82.0 if they wish to load icon files from their own codebase (which uses SVGR under-the-hood to import SVG files as React components).

```jsx
// old
<Icon source="add" />;

// new
import {PlusMinor} from '@shopify/polaris-icons';

<Icon source={PlusMinor} />;
```

The `untrusted` prop has been removed. Passing a string into the `source` prop now automatically implies an untrusted icon.

```jsx
// old
<Icon
untrusted
source="<svg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'><path d='M10.707 17.707l5-5a.999.999 0 1 0-1.414-1.414L11 14.586V3a1 1 0 1 0-2 0v11.586l-3.293-3.293a.999.999 0 1 0-1.414 1.414l5 5a.999.999 0 0 0 1.414 0' /></svg>"
/>;

// new
<Icon source="<svg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'><path d='M10.707 17.707l5-5a.999.999 0 1 0-1.414-1.414L11 14.586V3a1 1 0 1 0-2 0v11.586l-3.293-3.293a.999.999 0 1 0-1.414 1.414l5 5a.999.999 0 0 0 1.414 0' /></svg>" />;
```

### Modal <a name="polaris-modal"></a>

The `Modal.Dialog` subcomponent has been removed. This was an undocumented subcomponent for private usage only. It was never intended to be a public component.

### Navigation <a name="polaris-navigation"></a>

The `Navigation.UserMenu` subcomponent has been removed. Pass a `TopBar.UserMenu` into `TopBar`'s `userMenu` prop instead.

The `iconBody` prop has been removed from the `Navigation.Item` subcomponent. Pass a string or React Component into the `icon` prop instead.

```jsx
// old
<Navigation.Section
items={[
{
url: '/path/to/place',
label: 'Item',
iconBody:
"<svg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'><path d='M10.707 17.707l5-5a.999.999 0 1 0-1.414-1.414L11 14.586V3a1 1 0 1 0-2 0v11.586l-3.293-3.293a.999.999 0 1 0-1.414 1.414l5 5a.999.999 0 0 0 1.414 0' /></svg>",
},
]}
/>;

// new
<Navigation.Section
items={[
{
url: '/path/to/place',
label: 'Item',
icon:
"<svg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'><path d='M10.707 17.707l5-5a.999.999 0 1 0-1.414-1.414L11 14.586V3a1 1 0 1 0-2 0v11.586l-3.293-3.293a.999.999 0 1 0-1.414 1.414l5 5a.999.999 0 0 0 1.414 0' /></svg>",
},
]}
/>;
```

### Select <a name="polaris-select"></a>

The `groups` prop has been removed. Pass an array of groups into the `options` prop instead, which can now accept an array of groups or options.

```jsx
// old
<Select
groups={[
{
title: 'Group',
options: [
{label: 'Today', value: 'today'},
{label: 'Yesterday', value: 'yesterday'},
{label: 'Last 7 days', value: 'lastWeek'},
],
},
]}
/>;

// new
<Select
options={[
{
title: 'Group',
options: [
{label: 'Today', value: 'today'},
{label: 'Yesterday', value: 'yesterday'},
{label: 'Last 7 days', value: 'lastWeek'},
],
},
]}
/>;
```

### Tabs <a name="polaris-tabs"></a>

The `Tabs.Panel` subcomponent has been removed. This was a undocumented subcomponent for private usage only. It was never intended to be a public component.

## Removed Exports <a name="polaris-removed-exports"></a>

### WithContext <a name="polaris-withcontext"></a>

The `WithContext` component has been removed. It was used as a utility to handle multiple [legacy contexts](https://reactjs.org/docs/legacy-context.html) at once. Use [modern contexts](https://reactjs.org/docs/context.html#api) and access them using providers, hooks or `Class.contextType` instead.

```jsx
// old
function Test({context}) {
console.log(context);
return null;
}

const TestWithContext = withContext(Consumer)(Test);

// new with hooks
const TestContext1 = React.createContext('Polaris');

function Test() {
const testContext = React.useContext(TestContext1);
return <h1>{testContext}</h1>;
}

// new with contextType
const TestContext2 = React.createContext('Polaris');

class Test extends React.Component {
static contextType = TestContext2;

render() {
return <h1>{this.context}</h1>;
}
}
```

### WithRef <a name="polaris-withref"></a>

The `WithRef` component has been removed. It was used as a utlity to place refs on components wrapped in higher-order components. Use functional components instead.

### LinkLikeComponent <a name="polaris-linklikecomponent"></a>

The `LinkLikeComponent` type that describes argument you pass into `AppProvider`'s `link` prop has been removed. Use `AppProviderProps['linkComponent']` instead.

```jsx
// old
import {LinkLikeComponent} from '@shopify/polaris-react';

type Link = LinkLikeComponent;

// new
import {AppProviderProps} from '@shopify/polaris-react';

type Link = AppProviderProps['linkComponent'];
```

## Dependencies <a name="polaris-dependencies"></a>

The peer dependencies on `react` and `react-dom` have been increased to 16.8.6 to allow us to use hooks internally. Use `yarn` or `npm` to install a recent version of React.

```bash
# yarn
yarn add react react-dom

# npm
npm install react react-dom
```

## TypeScript <a name="polaris-typescript"></a>

Polaris now uses default imports for React. Because of this consuming applications that use Typescript must set the [esModuleInterop](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#support-for-import-d-from-cjs-from-commonjs-modules-with---esmoduleinterop) compiler option to `true` in their tsconfig.json. The TypeScript team recommend this option is enabled for all new projects.

```js
// tsconfig.json
{
"compilerOptions": {
"esModuleInterop": true,
}
}
```

## CDN Usage <a name="polaris-cdn"></a>

Polaris now uses [`unpkg.com`](https://unpkg.com) for hosting its static styles for CSS-only usage instead of using `sdks.shopifycdn.com`. Update any stylesheet imports to use the new URL.

```html
<!-- old -->
<link
rel="stylesheet"
href="https://sdks.shopifycdn.com/polaris/3.21.1/polaris.min.css"
/>

<!-- new -->
<link
rel="stylesheet"
href="https://unpkg.com/@shopify/polaris@4.0.0/styles.min.css"
/>
```