Skip to content

Commit ab13fc4

Browse files
committed
feat: pass pluginProps to wrapper
1 parent b81f409 commit ab13fc4

5 files changed

Lines changed: 24 additions & 11 deletions

File tree

README.rst

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,15 +251,16 @@ Wrap
251251
''''
252252

253253
Unlike Modify, the Wrap operation adds a React component around the widget, and a single widget can receive more than
254-
one wrap operation. Each wrapper function takes in a ``component`` and ``id`` prop.
254+
one wrap operation. Each wrapper function takes in a ``component``, ``id`` and ``pluginProps`` prop.
255255

256256
.. code-block::
257257
258-
const wrapWidget = ({ component, idx }) => (
258+
const wrapWidget = ({ component, idx, pluginProps }) => (
259259
<div className="bg-warning" data-testid={`wrapper${idx + 1}`} key={idx}>
260260
<p>This is a wrapper component that is placed around the widget.</p>
261261
{component}
262262
<p>With this wrapper, you can add anything before or after the widget.</p>
263+
<p>You can use the pluginProps to pass in any additional props to the wrapper: {pluginProps.prop1}</p>
263264
</div>
264265
);
265266
@@ -272,6 +273,9 @@ one wrap operation. Each wrapper function takes in a ``component`` and ``id`` pr
272273
{
273274
op: PLUGIN_OPERATIONS.Wrap,
274275
widgetId: 'default_contents',
276+
pluginProps: {
277+
prop1: 'prop1',
278+
},
275279
wrapper: wrapWidget,
276280
}
277281

src/plugins/PluginSlot.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ function BasePluginSlot({
9393
wrapComponent(
9494
() => container,
9595
pluginConfig.wrappers,
96+
pluginProps,
9697
),
9798
);
9899
} else {

src/plugins/PluginSlot.test.jsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import React from 'react';
44
import '@testing-library/jest-dom';
55
import classNames from 'classnames';
6-
import { render, fireEvent } from '@testing-library/react';
6+
import { render, fireEvent, within } from '@testing-library/react';
77
import userEvent from '@testing-library/user-event';
88
import { logError } from '@edx/frontend-platform/logging';
99
import { IntlProvider } from '@edx/frontend-platform/i18n';
@@ -78,14 +78,15 @@ function DefaultContents({ className, onClick, ...rest }) {
7878
);
7979
}
8080

81-
function PluginSlotWrapper({ slotOptions, children }) {
81+
function PluginSlotWrapper({ slotOptions, children, pluginProps }) {
8282
return (
8383
<IntlProvider locale="en">
8484
<PluginSlot
8585
id="test-slot"
8686
data-testid="test-slot-id"
8787
as="div"
8888
slotOptions={slotOptions}
89+
pluginProps={pluginProps}
8990
>
9091
{children}
9192
</PluginSlot>
@@ -182,20 +183,25 @@ describe('PluginSlot', () => {
182183
{
183184
op: PLUGIN_OPERATIONS.Wrap,
184185
widgetId: 'default_contents',
185-
wrapper: ({ component }) => (
186+
wrapper: ({ component, pluginProps }) => (
186187
<div data-testid="custom-wrapper">
187188
{component}
189+
<div data-testid="custom-wrapper-prop">
190+
{pluginProps.prop1}
191+
</div>
188192
</div>
189193
),
190194
},
191195
],
192196
keepDefault: true,
193197
});
194198

195-
const { getByTestId } = render(<TestPluginSlot />);
199+
const { getByTestId } = render(<TestPluginSlot pluginProps={{ prop1: 'prop1' }} />);
196200
const customWrapper = getByTestId('custom-wrapper');
197201
const defaultContent = getByTestId('default_contents');
198202
expect(customWrapper).toContainElement(defaultContent);
203+
const pluginProps = within(customWrapper).getByTestId('custom-wrapper-prop');
204+
expect(pluginProps).toHaveTextContent('prop1');
199205
});
200206

201207
it('should not render a widget if the Hide operation is applied to it', () => {

src/plugins/data/utils.jsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,14 @@ export const organizePlugins = (defaultContents, plugins) => {
8282
*
8383
* @param {Function} renderComponent - Function that returns JSX (i.e. React Component)
8484
* @param {Array} wrappers - Array of components that each use a "component" prop to render the wrapped contents
85+
* @params {object} pluginProps - Props defined in the PluginSlot
8586
* @returns {React.ReactElement} - The plugin component wrapped by any number of wrappers provided.
8687
*/
87-
export const wrapComponent = (renderComponent, wrappers) => wrappers.reduce(
88+
export const wrapComponent = (renderComponent, wrappers, pluginProps) => wrappers.reduce(
8889
// Disabled lint because currently we don't have a unique identifier for this
8990
// The "component" and "wrapper" are both functions
9091
// eslint-disable-next-line react/no-array-index-key
91-
(component, wrapper, idx) => React.createElement(wrapper, { component, key: idx }),
92+
(component, wrapper, idx) => React.createElement(wrapper, { component, key: idx, pluginProps }),
9293
renderComponent(),
9394
);
9495

src/plugins/data/utils.test.jsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ const mockIsAdminWrapper = ({ widget }) => {
2222
return isAdmin ? widget : null;
2323
};
2424

25-
const makeMockElementWrapper = (testId = 0) => function MockElementWrapper({ component }) {
25+
const makeMockElementWrapper = (testId = 0) => function MockElementWrapper({ component, pluginProps }) {
2626
return (
2727
<div data-testid={`wrapper${testId}`}>
28-
This is a wrapper.
28+
This is a wrapper with {pluginProps?.prop1}.
2929
{component}
3030
</div>
3131
);
@@ -181,14 +181,15 @@ describe('organizePlugins', () => {
181181
describe('wrapComponent', () => {
182182
describe('when provided with a single wrapper in an array', () => {
183183
it('should wrap the provided component', () => {
184-
const wrappedComponent = wrapComponent(mockRenderWidget, [makeMockElementWrapper()]);
184+
const wrappedComponent = wrapComponent(mockRenderWidget, [makeMockElementWrapper()], { prop1: 'prop1' });
185185

186186
const { getByTestId } = render(wrappedComponent);
187187

188188
const wrapper = getByTestId('wrapper0');
189189
const widget = getByTestId('widget');
190190

191191
expect(wrapper).toContainElement(widget);
192+
expect(wrapper).toHaveTextContent('This is a wrapper with prop1.');
192193
});
193194
});
194195
describe('when provided with multiple wrappers in an array', () => {

0 commit comments

Comments
 (0)