Skip to content

Commit

Permalink
Allow containing apps to manipulate the drag and drop context
Browse files Browse the repository at this point in the history
  • Loading branch information
cbeer committed Jun 17, 2020
1 parent c2619ad commit f896a3e
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 7 deletions.
18 changes: 16 additions & 2 deletions __tests__/src/components/AppProviders.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import { shallow } from 'enzyme';
import { ThemeProvider, StylesProvider } from '@material-ui/core/styles';
import Fullscreen from 'react-full-screen';
import { DndProvider } from 'react-dnd';
import { DndContext, DndProvider } from 'react-dnd';
import { AppProviders } from '../../../src/components/AppProviders';
import settings from '../../../src/config/settings';

Expand All @@ -29,7 +29,6 @@ describe('AppProviders', () => {
expect(wrapper.find(ThemeProvider).length).toBe(1);
expect(wrapper.find(StylesProvider).length).toBe(1);
expect(wrapper.find(Fullscreen).length).toBe(1);
expect(wrapper.find(DndProvider).length).toBe(1);
});

it('sets up a theme based on the config passed in merged w/ MaterialUI', () => {
Expand Down Expand Up @@ -71,4 +70,19 @@ describe('AppProviders', () => {
expect(wrapper.instance().i18n.language).toEqual('de');
});
});

it('provides a drag and drop context', () => {
const wrapper = createWrapper();
expect(wrapper.find('MaybeDndProvider').dive().find(DndProvider).length).toBe(1);
});

it('allows apps to opt-out of the drag and drop provider', () => {
const wrapper = createWrapper({ dndManager: false });
expect(wrapper.find('MaybeDndProvider').dive().find(DndProvider).length).toBe(0);
});

it('allows apps to provide an existing drag and drop context', () => {
const wrapper = createWrapper({ dndManager: 'whatever' });
expect(wrapper.find('MaybeDndProvider').dive().find(DndContext.Provider).prop('value')).toBe('whatever');
});
});
6 changes: 4 additions & 2 deletions src/components/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ export class App extends Component {
* @return {String} - HTML markup for the component
*/
render() {
const { plugins } = this.props;
const { dndManager, plugins } = this.props;

return (
<PluginProvider plugins={plugins}>
<AppProviders>
<AppProviders dndManager={dndManager}>
<AuthenticationSender />
<AccessTokenSender />
<Suspense
Expand All @@ -37,10 +37,12 @@ export class App extends Component {
}

App.propTypes = {
dndManager: PropTypes.object, // eslint-disable-line react/forbid-prop-types
plugins: PropTypes.array, // eslint-disable-line react/forbid-prop-types
};

App.defaultProps = {
dndManager: undefined,
plugins: [],
};

Expand Down
32 changes: 29 additions & 3 deletions src/components/AppProviders.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { LiveAnnouncer } from 'react-aria-live';
import {
ThemeProvider, StylesProvider, createMuiTheme, jssPreset, createGenerateClassName,
} from '@material-ui/core/styles';
import { DndProvider } from 'react-dnd';
import { DndContext, DndProvider } from 'react-dnd';
import MultiBackend from 'react-dnd-multi-backend';
import HTML5toTouch from 'react-dnd-multi-backend/dist/cjs/HTML5toTouch';
import { create } from 'jss';
Expand Down Expand Up @@ -49,6 +49,7 @@ export class AppProviders extends Component {
render() {
const {
children, classPrefix, isFullscreenEnabled, setWorkspaceFullscreen, theme, translations,
dndManager,
} = this.props;

const generateClassName = createGenerateClassName({
Expand All @@ -59,6 +60,29 @@ export class AppProviders extends Component {
this.i18n.addResourceBundle(lng, 'translation', translations[lng], true, true);
});

/**
* Allow applications to opt-out of (or provide their own) drag and drop context
*/
const MaybeDndProvider = (props) => {
if (dndManager === false) {
return props.children;
}

if (dndManager === undefined) {
return (
<DndProvider backend={MultiBackend} options={HTML5toTouch}>
{props.children}
</DndProvider>
);
}

return (
<DndContext.Provider value={dndManager}>
{props.children}
</DndContext.Provider>
);
};

return (
<Fullscreen
enabled={isFullscreenEnabled}
Expand All @@ -73,9 +97,9 @@ export class AppProviders extends Component {
jss={create({ plugins: [...jssPreset().plugins, rtl()] })}
generateClassName={generateClassName}
>
<DndProvider backend={MultiBackend} options={HTML5toTouch}>
<MaybeDndProvider>
{children}
</DndProvider>
</MaybeDndProvider>
</StylesProvider>
</ThemeProvider>
</LiveAnnouncer>
Expand All @@ -88,6 +112,7 @@ export class AppProviders extends Component {
AppProviders.propTypes = {
children: PropTypes.node,
classPrefix: PropTypes.string,
dndManager: PropTypes.object, // eslint-disable-line react/forbid-prop-types
isFullscreenEnabled: PropTypes.bool,
language: PropTypes.string.isRequired,
setWorkspaceFullscreen: PropTypes.func.isRequired,
Expand All @@ -98,5 +123,6 @@ AppProviders.propTypes = {
AppProviders.defaultProps = {
children: null,
classPrefix: '',
dndManager: undefined,
isFullscreenEnabled: false,
};

0 comments on commit f896a3e

Please sign in to comment.