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

Update context #1459

Closed
wants to merge 12 commits into from
1 change: 1 addition & 0 deletions UNRELEASED-V4.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Use [the changelog guidelines](https://git.io/polaris-changelog-guidelines) to f

### 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))
- 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))
Expand Down
14 changes: 6 additions & 8 deletions src/components/AppProvider/AppProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
ScrollLockManager,
createAppProviderContext,
} from './utilities';
import AppProviderContext from './Context';
import AppProviderContext from './context';
import {AppProviderProps, AppProviderContextType} from './types';

interface State {
Expand Down Expand Up @@ -75,16 +75,14 @@ export default class AppProvider extends React.Component<Props, State> {
});
}

get getContext(): AppProviderContextType {
return this.state.context;
}

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

return (
<AppProviderContext.Provider value={this.getContext}>
<AppProviderContext.Provider value={context}>
<ThemeProvider theme={theme}>
{React.Children.only(this.props.children)}
{React.Children.only(children)}
</ThemeProvider>
</AppProviderContext.Provider>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/AppProvider/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ export {
CreateAppProviderContext,
} from './utilities';
export {AppProviderProps as Props, AppProviderContextType} from './types';
export {default as AppProviderContext} from './Context';
export {default as AppProviderContext} from './context';
export {default} from './AppProvider';
2 changes: 1 addition & 1 deletion src/components/AppProvider/tests/AppProvider.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import AppProviderContext from '../Context';
import AppProviderContext from '../context';
import AppProvider from '../AppProvider';
import {mountWithAppProvider} from '../../../test-utilities';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {PolarisContext} from '../../../types';
import {
createThemeContext,
ThemeProviderContext as CreateThemeContext,
ThemeProviderContextType as CreateThemeContext,
} from '../../../ThemeProvider';
import {AppProviderProps} from '../../types';
import StickyManager from '../StickyManager';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import {mount} from 'enzyme';
import AppProviderContext from '../../../Context';
import AppProviderContext from '../../../context';
import withAppProvider from '../withAppProvider';

describe('withAppProvider', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import Link from '../Link';
import StickyManager from '../StickyManager';
import ScrollLockManager from '../ScrollLockManager';
import {
ThemeProviderContextType,
ThemeProviderContext,
Consumer as ThemeProviderConsumer,
} from '../../../ThemeProvider';
import {PolarisContext} from '../../../types';
import AppProviderContext from '../../Context';
import AppProviderContext from '../../context';

export type ReactComponent<P, C> =
| React.ComponentClass<P> & C
Expand All @@ -22,7 +22,7 @@ export interface WithAppProviderProps {
link: Link;
stickyManager: StickyManager;
scrollLockManager: ScrollLockManager;
theme?: ThemeProviderContext;
theme?: ThemeProviderContextType;
appBridge?: ClientApplication<{}>;
};
}
Expand Down Expand Up @@ -72,7 +72,7 @@ export default function withAppProvider<OwnProps>({
<AppProviderContext.Consumer>
{(polaris) => {
return (
<ThemeProviderConsumer>
<ThemeProviderContext.Consumer>
{(polarisTheme) => {
const polarisContext: PolarisContext = {
...polaris,
Expand All @@ -94,7 +94,7 @@ export default function withAppProvider<OwnProps>({
/>
);
}}
</ThemeProviderConsumer>
</ThemeProviderContext.Consumer>
);
}}
</AppProviderContext.Consumer>
Expand Down
40 changes: 22 additions & 18 deletions src/components/Autocomplete/components/ComboBox/ComboBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import ActionList from '../../../ActionList';
import Popover from '../../../Popover';
import {PreferredPosition} from '../../../PositionedOverlay';
import {ActionListItemDescriptor, Key} from '../../../../types';
import {ComboBoxContext} from '../types';
import KeypressListener from '../../../KeypressListener';
import {TextField, Provider} from './components';
import ComboBoxContext, {ComboBoxContextType} from './context';
import {TextField} from './components';

import styles from './ComboBox.scss';

Expand Down Expand Up @@ -119,13 +119,6 @@ export default class ComboBox extends React.PureComponent<Props, State> {
HTMLDivElement
> = React.createRef();

get getContext(): ComboBoxContext {
return {
comboBoxId: this.state.comboBoxId,
selectedOptionId: this.selectedOptionId,
};
}

componentDidMount() {
const {options, actionsBefore, actionsAfter} = this.props;
const comboBoxId = this.getComboBoxId();
Expand Down Expand Up @@ -206,6 +199,12 @@ export default class ComboBox extends React.PureComponent<Props, State> {
onEndReached,
emptyState,
} = this.props;
const {
comboBoxId,
navigableOptions,
selectedOptions,
popoverActive,
} = this.state;

const actionsBeforeMarkup = actionsBefore &&
actionsBefore.length > 0 && (
Expand All @@ -221,9 +220,9 @@ export default class ComboBox extends React.PureComponent<Props, State> {
<OptionList
role="presentation"
optionRole="option"
options={filterForOptions(this.state.navigableOptions)}
options={filterForOptions(navigableOptions)}
onChange={this.selectOptions}
selected={this.state.selectedOptions}
selected={selectedOptions}
title={listTitle}
allowMultiple={allowMultiple}
/>
Expand All @@ -240,14 +239,19 @@ export default class ComboBox extends React.PureComponent<Props, State> {
options.length === 0 &&
emptyState && <div className={styles.EmptyState}>{emptyState}</div>;

const context: ComboBoxContextType = {
comboBoxId,
selectedOptionId: this.selectedOptionId,
};

return (
<Provider value={this.getContext}>
<ComboBoxContext.Provider value={context}>
<div
onClick={this.handleClick}
role="combobox"
aria-expanded={this.state.popoverActive}
aria-owns={this.state.comboBoxId}
aria-controls={this.state.comboBoxId}
aria-expanded={popoverActive}
aria-owns={comboBoxId}
aria-controls={comboBoxId}
aria-haspopup
onFocus={this.handleFocus}
onBlur={this.handleBlur}
Expand All @@ -268,14 +272,14 @@ export default class ComboBox extends React.PureComponent<Props, State> {
/>
<Popover
activator={textField}
active={this.state.popoverActive}
active={popoverActive}
onClose={this.handlePopoverClose}
preferredPosition={preferredPosition}
fullWidth
preventAutofocus
>
<div
id={this.state.comboBoxId}
id={comboBoxId}
role="listbox"
aria-multiselectable={allowMultiple}
>
Expand All @@ -289,7 +293,7 @@ export default class ComboBox extends React.PureComponent<Props, State> {
</div>
</Popover>
</div>
</Provider>
</ComboBoxContext.Provider>
);
}

Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import * as React from 'react';

import {ComboBoxContext} from '../../../types';
import ComboBoxContext, {ComboBoxContextType} from '../../context';
import BaseTextField, {Props as TextFieldProps} from '../../../../../TextField';
import {Consumer} from '../Context';

export default function TextField(props: TextFieldProps) {
return (
<Consumer>
{({selectedOptionId, comboBoxId}: ComboBoxContext) => (
<ComboBoxContext.Consumer>
{({selectedOptionId, comboBoxId}: ComboBoxContextType) => (
<BaseTextField
{...props}
autoComplete={false}
Expand All @@ -16,6 +15,6 @@ export default function TextField(props: TextFieldProps) {
ariaControls={comboBoxId}
/>
)}
</Consumer>
</ComboBoxContext.Consumer>
);
}
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export {default as TextField} from './TextField';
export {Provider, Consumer} from './Context';
10 changes: 10 additions & 0 deletions src/components/Autocomplete/components/ComboBox/context.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import * as React from 'react';

export interface ComboBoxContextType {
comboBoxId?: string;
selectedOptionId?: string;
}

const ComboBoxContext = React.createContext<ComboBoxContextType>({});

export default ComboBoxContext;
4 changes: 0 additions & 4 deletions src/components/Autocomplete/components/types.ts

This file was deleted.

10 changes: 7 additions & 3 deletions src/components/Banner/Banner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ import Heading from '../Heading';
import ButtonGroup from '../ButtonGroup';
import UnstyledLink from '../UnstyledLink';
import Icon, {Props as IconProps} from '../Icon';
import {Consumer, WithinContentContext} from '../WithinContentContext';
import WithinContentContext, {
WithinContentContextType,
} from '../WithinContentContext';
import withContext from '../WithContext';
import {withAppProvider, WithAppProviderProps} from '../AppProvider';

Expand All @@ -45,7 +47,7 @@ export interface Props {
onDismiss?(): void;
}

export type CombinedProps = Props & WithContextTypes<WithinContentContext>;
export type CombinedProps = Props & WithContextTypes<WithinContentContextType>;

export class Banner extends React.PureComponent<CombinedProps, never> {
render() {
Expand Down Expand Up @@ -206,6 +208,8 @@ function secondaryActionFrom(action: Action) {
}

export default compose<Props>(
withContext<Props, WithAppProviderProps, WithinContentContext>(Consumer),
withContext<Props, WithAppProviderProps, WithinContentContextType>(
WithinContentContext.Consumer,
),
withAppProvider(),
)(Banner);
6 changes: 3 additions & 3 deletions src/components/Banner/tests/Banner.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
import {mountWithAppProvider} from 'test-utilities';
import {Button, Icon, UnstyledLink, Heading} from 'components';
import Banner from '..';
import {Provider} from '../../WithinContentContext';
import WithinContentContext from '../../WithinContentContext';

describe('<Banner />', () => {
it('renders a title', () => {
Expand Down Expand Up @@ -100,15 +100,15 @@ describe('<Banner />', () => {
};

const bannerWithContentContext = mountWithAppProvider(
<Provider value={mockContext}>
<WithinContentContext.Provider value={mockContext}>
<Banner
action={{
content: 'Primary action',
}}
>
Some content
</Banner>
</Provider>,
</WithinContentContext.Provider>,
);

it('renders a slim button with contentContext', () => {
Expand Down
18 changes: 9 additions & 9 deletions src/components/Card/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import {classNames} from '@shopify/react-utilities/styles';
import {Action, DisableableAction} from '../../types';
import {buttonFrom} from '../Button';
import ButtonGroup from '../ButtonGroup';
import {Provider, WithinContentContext} from '../WithinContentContext';
import WithinContentContext, {
WithinContentContextType,
} from '../WithinContentContext';

import {Header, Section} from './components';
import styles from './Card.scss';
Expand Down Expand Up @@ -66,20 +68,18 @@ export default class Card extends React.PureComponent<Props, never> {
</div>
) : null;

const context: WithinContentContextType = {
withinContentContainer: true,
};

return (
<Provider value={this.getContext}>
<WithinContentContext.Provider value={context}>
<div className={className}>
{headerMarkup}
{content}
{footerMarkup}
</div>
</Provider>
</WithinContentContext.Provider>
);
}

get getContext(): WithinContentContext {
return {
withinContentContainer: true,
};
}
}
10 changes: 6 additions & 4 deletions src/components/Card/tests/Card.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,23 @@ import * as React from 'react';
import {mountWithAppProvider} from 'test-utilities';
import {Card, Badge, Button} from 'components';

import {Consumer, WithinContentContext} from '../../WithinContentContext';
import WithinContentContext, {
WithinContentContextType,
} from '../../WithinContentContext';

describe('<Card />', () => {
it('has a child with prop withinContentContainer set to true', () => {
function TestComponent(_: WithinContentContext) {
function TestComponent(_: WithinContentContextType) {
return null;
}

const component = mountWithAppProvider(
<Card>
<Consumer>
<WithinContentContext.Consumer>
{(props) => {
return <TestComponent {...props} />;
}}
</Consumer>
</WithinContentContext.Consumer>
</Card>,
);

Expand Down
Loading