Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v4] Update React - preparations #1392

Merged
merged 16 commits into from
May 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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' {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was causing namespace issues

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', () => {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test will be updated and improved when we switch AppProvider to the new context API

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;