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

[AppProvider] Update context #1424

Merged
merged 5 commits into from
May 15, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
43 changes: 12 additions & 31 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 from './Context';
import {AppProviderProps, AppProviderContextType} 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,29 @@ 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;
get getContext(): AppProviderContextType {
return this.state.context;
}

render() {
const {theme = {logo: null}} = this.props;
return (
<ThemeProvider theme={theme}>
{React.Children.only(this.props.children)}
</ThemeProvider>
<AppProviderContext.Provider value={this.getContext}>
<ThemeProvider theme={theme}>
{React.Children.only(this.props.children)}
</ThemeProvider>
</AppProviderContext.Provider>
);
}

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

unsubscribe = (callback: () => void) => {
this.subscriptions = this.subscriptions.filter(
(subscription) => subscription !== callback,
);
};
}
9 changes: 9 additions & 0 deletions src/components/AppProvider/Context.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import * as React from 'react';
import {AppProviderContextType} from './types';
import createPolarisContext from './utilities/createPolarisContext';

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, AppProviderContextType} from './types';
export {default as AppProviderContext} from './Context';
export {default} from './AppProvider';
35 changes: 15 additions & 20 deletions src/components/AppProvider/tests/AppProvider.test.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,28 @@
import * as React from 'react';
import {mount} from 'enzyme';
import {polarisAppProviderContextTypes} from '../types';
import AppProviderContext from '../Context';
import AppProvider from '../AppProvider';
import {mountWithAppProvider} from '../../../test-utilities';

describe('<AppProvider />', () => {
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);
});
});
25 changes: 7 additions & 18 deletions src/components/AppProvider/types.ts
Original file line number Diff line number Diff line change
@@ -1,8 +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 {Theme} from '../ThemeProvider';
import {
Intl,
Link,
Expand Down Expand Up @@ -30,19 +28,10 @@ export interface AppProviderProps {
theme?: Theme;
}

export interface Context {
polaris: {
Copy link
Member Author

Choose a reason for hiding this comment

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

Removing the polaris namespace now since we consume it from a render prop rather than context types. We won't have to worry about collisions now

intl: Intl;
link: Link;
stickyManager: StickyManager;
scrollLockManager: ScrollLockManager;
subscribe?(callback: () => void): void;
unsubscribe?(callback: () => void): void;
appBridge?: ClientApplication<{}>;
};
export interface AppProviderContextType {
intl: Intl;
link: Link;
stickyManager: StickyManager;
scrollLockManager: ScrollLockManager;
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;
Copy link
Member Author

Choose a reason for hiding this comment

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

There was a type issue and boundElement could be undefined

/** 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;
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import {noop} from '@shopify/javascript-utilities/other';
import createApp, {
getShopOrigin,
LifecycleHook,
DispatchActionHook,
} from '@shopify/app-bridge';
import {AppProviderProps, Context} from '../../types';
import {StickyManager} from '../withSticky';
import {AppProviderProps, AppProviderContextType} from '../../types';
import StickyManager from '../StickyManager';
import ScrollLockManager from '../ScrollLockManager';
import Intl from '../Intl';
import Link from '../Link';
Expand All @@ -14,8 +13,6 @@ import {polarisVersion} from '../../../../configure';
export interface CreateAppProviderContext extends AppProviderProps {
stickyManager?: StickyManager;
scrollLockManager?: ScrollLockManager;
subscribe?(callback: () => void): void;
unsubscribe?(callback: () => void): void;
}

export default function createAppProviderContext({
Expand All @@ -26,9 +23,7 @@ export default function createAppProviderContext({
forceRedirect,
stickyManager,
scrollLockManager,
subscribe = noop,
unsubscribe = noop,
}: CreateAppProviderContext = {}): Context {
}: CreateAppProviderContext = {}): AppProviderContextType {
const intl = new Intl(i18n);
const link = new Link(linkComponent);
const appBridge = apiKey
Expand All @@ -44,15 +39,11 @@ export default function createAppProviderContext({
}

return {
polaris: {
intl,
link,
stickyManager: stickyManager || new StickyManager(),
scrollLockManager: scrollLockManager || new ScrollLockManager(),
subscribe,
unsubscribe,
appBridge,
},
intl,
link,
stickyManager: stickyManager || new StickyManager(),
scrollLockManager: scrollLockManager || new ScrollLockManager(),
appBridge,
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import * as React from 'react';
import * as appBridge from '@shopify/app-bridge';
import {noop} from '@shopify/javascript-utilities/other';
import * as targets from '@shopify/react-utilities/target';
import createAppProviderContext, {
setClientInterfaceHook,
} from '../createAppProviderContext';
import {StickyManager} from '../../withSticky';
import StickyManager from '../../StickyManager';
import ScrollLockManager from '../../ScrollLockManager';

jest.mock('../../Intl', () => ({
Expand Down Expand Up @@ -41,15 +40,11 @@ describe('createAppProviderContext()', () => {
const context = createAppProviderContext();

expect(context).toMatchObject({
polaris: {
intl: expect.any(Intl),
link: expect.any(Link),
stickyManager: expect.any(StickyManager),
scrollLockManager: expect.any(ScrollLockManager),
subscribe: noop,
unsubscribe: noop,
appBridge: undefined,
},
intl: expect.any(Intl),
link: expect.any(Link),
stickyManager: expect.any(StickyManager),
scrollLockManager: expect.any(ScrollLockManager),
appBridge: undefined,
});
});

Expand Down Expand Up @@ -86,24 +81,20 @@ describe('createAppProviderContext()', () => {
});

expect(context).toMatchObject({
polaris: {
intl: expect.any(Intl),
link: expect.any(Link),
stickyManager: expect.any(StickyManager),
scrollLockManager: expect.any(ScrollLockManager),
subscribe: noop,
unsubscribe: noop,
appBridge: {
apiKey,
forceRedirect: undefined,
shopOrigin: undefined,
dispatch: expect.any(Function),
localOrigin: '',
featuresAvailable: expect.any(Function),
getState: expect.any(Function),
subscribe: expect.any(Function),
error: expect.any(Function),
},
intl: expect.any(Intl),
link: expect.any(Link),
stickyManager: expect.any(StickyManager),
scrollLockManager: expect.any(ScrollLockManager),
appBridge: {
apiKey,
forceRedirect: undefined,
shopOrigin: undefined,
dispatch: expect.any(Function),
localOrigin: '',
featuresAvailable: expect.any(Function),
getState: expect.any(Function),
subscribe: expect.any(Function),
error: expect.any(Function),
},
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import {PolarisContext} from '../../../types';
import {
createThemeContext,
ThemeContext as CreateThemeContext,
ThemeProviderContext as CreateThemeContext,
} from '../../../ThemeProvider';
import {AppProviderProps} from '../../types';
import {StickyManager} from '../withSticky';
import StickyManager from '../StickyManager';
import createAppProviderContext, {
CreateAppProviderContext,
} from '../createAppProviderContext';
Expand Down Expand Up @@ -42,5 +42,5 @@ export default function createPolarisContext(
? createThemeContext(themeContext)
: createThemeContext();

return {...appProvider, ...theme};
return {...appProvider, theme};
}
Loading