Skip to content

Commit

Permalink
Merge pull request #1392 from Shopify/update-react
Browse files Browse the repository at this point in the history
[v4] Update React - preparations
  • Loading branch information
AndrewMusgrave committed May 15, 2019
2 parents dc0377d + 623cd1f commit cb8a3f7
Show file tree
Hide file tree
Showing 151 changed files with 1,806 additions and 1,841 deletions.
5 changes: 5 additions & 0 deletions UNRELEASED-V4.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,14 @@ Use [the changelog guidelines](https://git.io/polaris-changelog-guidelines) to f

### Dependency upgrades

- Update `react` to 16.8.6 and `enzyme` to 3.9.1 ([#1392](https://github.com/Shopify/polaris-react/pull/1392))

### Code quality

- Updated all our context files to export react context rather than a provider and consumer ([#1459](https://github.com/Shopify/polaris-react/pull/1459))
- Upgraded the `Autocomplete` component from legacy context API to use createContext ([#1403](https://github.com/Shopify/polaris-react/pull/1403))
- Removed testID warning in tests ([#1447](https://github.com/Shopify/polaris-react/pull/1447))
- Updated `ThemeProvider` to use the new context api ([#1396](https://github.com/Shopify/polaris-react/pull/1396))
- Updated `AppProvider` to no longer use `componentWillReceiveProps`([#1255](https://github.com/Shopify/polaris-react/pull/1255))
- Upgraded the `Navigation` component from legacy context API to use createContext ([#1402](https://github.com/Shopify/polaris-react/pull/1402))
- Updated `ThemeProvider` to no longer use `componentWillReceiveProps`([#1254](https://github.com/Shopify/polaris-react/pull/1254))
Expand Down
5 changes: 0 additions & 5 deletions config/typescript/prop-types.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +0,0 @@
// https://github.com/Microsoft/TypeScript/issues/24599
declare module 'prop-types' {
const content: any;
export = content;
}
16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@
"@storybook/addon-notes": "^4.1.6",
"@storybook/addon-options": "^4.1.6",
"@storybook/react": "^4.1.6",
"@types/enzyme": "^3.1.14",
"@types/enzyme-adapter-react-16": "^1.0.3",
"@types/enzyme": "^3.9.1",
"@types/enzyme-adapter-react-16": "^1.0.5",
"@types/lodash": "^4.14.108",
"@types/node": "^8.10.17",
"archiver": "^2.1.0",
Expand All @@ -117,8 +117,8 @@
"copyfiles": "^1.2.0",
"crypto": "^1.0.1",
"cssnano": "^4.1.8",
"enzyme": "^3.7.0",
"enzyme-adapter-react-16": "^1.6.0",
"enzyme": "^3.9.0",
"enzyme-adapter-react-16": "^1.12.1",
"fs-extra": "^4.0.2",
"generic-names": "^1.0.2",
"glob": "^7.1.2",
Expand All @@ -139,8 +139,8 @@
"postcss-modules-values": "^2.0.0",
"postcss-shopify": "^2.2.0",
"puppeteer": "^1.5.0",
"react": "^16.4.0",
"react-dom": "^16.4.0",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-test-renderer": "^16.3.1",
"rimraf": "^2.6.1",
"rollup": "^1.0.2",
Expand Down Expand Up @@ -183,8 +183,8 @@
"@shopify/react-compose": "^0.1.6",
"@shopify/react-utilities": "^2.0.3",
"@types/prop-types": "^15.5.5",
"@types/react": "^16.4.7",
"@types/react-dom": "^16.0.6",
"@types/react": "^16.8.15",
"@types/react-dom": "^16.8.4",
"@types/react-transition-group": "^2.0.7",
"core-js": "^2.5.1",
"hoist-non-react-statics": "^2.5.0",
Expand Down
47 changes: 13 additions & 34 deletions src/components/AppProvider/AppProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,11 @@ import {
ScrollLockManager,
createAppProviderContext,
} from './utilities';
import {
AppProviderProps,
Context,
polarisAppProviderContextTypes,
} from './types';
import AppProviderContext, {AppProviderContextType} from './context';
import {AppProviderProps} from './types';

interface State {
polaris: Context;
context: AppProviderContextType;
}

// The script in the styleguide that generates the Props Explorer data expects
Expand All @@ -22,10 +19,8 @@ interface State {
interface Props extends AppProviderProps {}

export default class AppProvider extends React.Component<Props, State> {
static childContextTypes = polarisAppProviderContextTypes;
private stickyManager: StickyManager;
private scrollLockManager: ScrollLockManager;
private subscriptions: {(): void}[] = [];

constructor(props: Props) {
super(props);
Expand All @@ -34,12 +29,10 @@ export default class AppProvider extends React.Component<Props, State> {
const {theme, children, ...rest} = this.props;

this.state = {
polaris: createAppProviderContext({
context: createAppProviderContext({
...rest,
stickyManager: this.stickyManager,
scrollLockManager: this.scrollLockManager,
subscribe: this.subscribe,
unsubscribe: this.unsubscribe,
}),
};
}
Expand Down Expand Up @@ -71,41 +64,27 @@ export default class AppProvider extends React.Component<Props, State> {

// eslint-disable-next-line react/no-did-update-set-state
this.setState({
polaris: createAppProviderContext({
context: createAppProviderContext({
i18n,
linkComponent,
apiKey,
shopOrigin,
forceRedirect,
stickyManager: this.stickyManager,
subscribe: this.subscribe,
unsubscribe: this.unsubscribe,
}),
});

this.subscriptions.forEach((subscriberCallback) => subscriberCallback());
}

getChildContext(): Context {
return this.state.polaris;
}

render() {
const {theme = {logo: null}} = this.props;
const {theme = {logo: null}, children} = this.props;
const {context} = this.state;

return (
<ThemeProvider theme={theme}>
{React.Children.only(this.props.children)}
</ThemeProvider>
<AppProviderContext.Provider value={context}>
<ThemeProvider theme={theme}>
{React.Children.only(children)}
</ThemeProvider>
</AppProviderContext.Provider>
);
}

subscribe = (callback: () => void) => {
this.subscriptions.push(callback);
};

unsubscribe = (callback: () => void) => {
this.subscriptions = this.subscriptions.filter(
(subscription) => subscription !== callback,
);
};
}
18 changes: 18 additions & 0 deletions src/components/AppProvider/context.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import * as React from 'react';
import {ClientApplication} from '@shopify/app-bridge';
import createPolarisContext from './utilities/createPolarisContext';
import {Intl, Link, StickyManager, ScrollLockManager} from './utilities';

export interface AppProviderContextType {
intl: Intl;
link: Link;
stickyManager: StickyManager;
scrollLockManager: ScrollLockManager;
appBridge?: ClientApplication<{}>;
}

const AppProviderContext = React.createContext<AppProviderContextType>(
createPolarisContext(),
);

export default AppProviderContext;
8 changes: 2 additions & 6 deletions src/components/AppProvider/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,12 @@ export {
withAppProvider,
createAppProviderContext,
createPolarisContext,
withSticky,
WithAppProviderProps,
TranslationDictionary,
PrimitiveReplacementDictionary,
ComplexReplacementDictionary,
CreateAppProviderContext,
} from './utilities';
export {
AppProviderProps as Props,
Context,
polarisAppProviderContextTypes,
} from './types';
export {AppProviderProps as Props} from './types';
export {default as AppProviderContext, AppProviderContextType} from './context';
export {default} from './AppProvider';
83 changes: 15 additions & 68 deletions src/components/AppProvider/tests/AppProvider.test.tsx
Original file line number Diff line number Diff line change
@@ -1,81 +1,28 @@
import * as React from 'react';
import TestUtils from 'react-dom/test-utils';
import {mount} from 'enzyme';
import {createThemeContext} from '../../ThemeProvider';
import {StickyManager, createAppProviderContext} from '../utilities';
import {polarisAppProviderContextTypes} from '../types';
import AppProviderContext from '../context';
import AppProvider from '../AppProvider';
import {mountWithAppProvider} from '../../../test-utilities';

describe('<AppProvider />', () => {
it('passes i18n and withComponent properties to context', () => {
const i18n = {
Polaris: {
Common: {
undo: 'Custom Undo',
},
},
};
const CustomLinkComponent = () => {
return <a href="test">Custom Link Component</a>;
};
const stickyManager = new StickyManager(document);
const context = {
...createAppProviderContext({
i18n,
linkComponent: CustomLinkComponent,
stickyManager,
}),
...createThemeContext(),
};

// eslint-disable-next-line react/prefer-stateless-function
class Child extends React.Component {
static contextTypes = polarisAppProviderContextTypes;

render() {
return <div />;
}
}

const wrapper = TestUtils.renderIntoDocument(
<AppProvider i18n={i18n} linkComponent={CustomLinkComponent}>
<Child />
</AppProvider>,
);

const child = TestUtils.findRenderedComponentWithType(
wrapper as React.Component,
Child,
);

// https://github.com/facebook/jest/issues/1772
expect(JSON.stringify(child.context)).toBe(JSON.stringify(context));
});

it('updates polaris context when props change', () => {
const CustomLinkComponent = () => {
return <a href="test">Custom Link Component</a>;
};

// eslint-disable-next-line react/prefer-stateless-function
class Child extends React.Component {
static contextTypes = polarisAppProviderContextTypes;

render() {
return <div />;
}
}
const Child: React.SFC<{}> = (_props) => (
<AppProviderContext.Consumer>
{({link: {linkComponent}}) =>
linkComponent ? <div id="child" /> : null
}
</AppProviderContext.Consumer>
);
const LinkComponent = () => <div />;

const wrapper = mount(
const wrapper = mountWithAppProvider(
<AppProvider>
<Child />
</AppProvider>,
);

wrapper.setProps({linkComponent: CustomLinkComponent});

expect(
wrapper.find(Child).instance().context.polaris.link.linkComponent,
).toBe(CustomLinkComponent);
expect(wrapper.find('#child')).toHaveLength(0);
wrapper.setProps({linkComponent: LinkComponent});
wrapper.update();
expect(wrapper.find('#child')).toHaveLength(1);
});
});
30 changes: 2 additions & 28 deletions src/components/AppProvider/types.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
import {ClientApplication} from '@shopify/app-bridge';
import {ValidationMap} from 'react';
import * as PropTypes from 'prop-types';
import {LinkLikeComponent} from '../UnstyledLink';
import {Theme, THEME_CONTEXT_TYPES as polarisTheme} from '../ThemeProvider';
import {
Intl,
Link,
StickyManager,
ScrollLockManager,
TranslationDictionary,
} from './utilities';
import {Theme} from '../ThemeProvider';
import {TranslationDictionary} from './utilities';

export interface AppProviderProps {
/** A locale object or array of locale objects that overrides default translations */
Expand All @@ -29,20 +20,3 @@ export interface AppProviderProps {
/** Custom logos and colors provided to select components */
theme?: Theme;
}

export interface Context {
polaris: {
intl: Intl;
link: Link;
stickyManager: StickyManager;
scrollLockManager: ScrollLockManager;
subscribe?(callback: () => void): void;
unsubscribe?(callback: () => void): void;
appBridge?: ClientApplication<{}>;
};
}

export const polarisAppProviderContextTypes: ValidationMap<any> = {
polaris: PropTypes.any,
...polarisTheme,
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export interface StickyItem {
/** Placeholder element */
placeHolderNode: HTMLElement;
/** Element outlining the fixed position boundaries */
boundingElement: HTMLElement | null;
boundingElement?: HTMLElement | null;
/** Offset vertical spacing from the top of the scrollable container */
offset: boolean;
/** Should the element remain in a fixed position when the layout is stacked (smaller screens) */
Expand Down
3 changes: 3 additions & 0 deletions src/components/AppProvider/utilities/StickyManager/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import StickyManager from './StickyManager';

export default StickyManager;

0 comments on commit cb8a3f7

Please sign in to comment.