Skip to content

Commit 496f198

Browse files
authored
Mfrank/rename variables (openedx#17)
* fix: rename variables * docs: update readme --------- Co-authored-by: Maxwell Frank <mfrank@2u.com>
1 parent 94dd7ad commit 496f198

File tree

7 files changed

+39
-23
lines changed

7 files changed

+39
-23
lines changed

README.rst

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,24 @@ Getting Started
2929
1. Add Library Dependency
3030
-------------------------
3131

32-
Add `@edx/frontend-plugin-framework` to the `package.json` of both Host and Child MFEs.
32+
Add ``@edx/frontend-plugin-framework`` to the ``package.json`` of both Host and Child MFEs.
3333

3434
Micro-frontend configuration document (JS)
3535
------------------------------------------
3636

3737
Micro-frontends that would like to use the Plugin Framework need to be configured via a JavaScript configuration
38-
document and a `plugins` config. Technically, only the Host MFE would require an `env.config.js` file with a `plugins` config.
39-
Keep in mind that since any Child MFE can theoretically also contain its own PluginSlot, it will eventually need its own
40-
JavaScript configuration.
38+
document and a ``pluginSlots`` config. Technically, only the Host MFE requires an ``env.config.js`` file with a ``pluginSlots`` config.
39+
40+
However, note that any Child MFE can theoretically contain one or more ``PluginSlot`` components, thereby making it both a Child MFE and a Host MFE.
41+
In this instance, it would have its own JavaScript file to configure the ``PluginSlot``.
42+
43+
For more information on how JS based configuration works, see the `config.js`_ file in frontend-platform.
4144

4245
.. code-block::
4346
4447
const config = {
4548
// other existing configuration
46-
plugins: {
49+
pluginSlots: {
4750
sidebar: {
4851
keepDefault: false, // bool to keep default host content
4952
plugins: [
@@ -56,10 +59,12 @@ JavaScript configuration.
5659
}
5760
}
5861
62+
.. _config.js: https://github.com/openedx/frontend-platform/blob/556424ee073e0629d7331046bbd7714d0d241f43/src/config.js
63+
5964
Host Micro-frontend (JSX)
6065
-------------------------
6166

62-
Hosts must define PluginSlot components in areas of the UI where they intend to accept extensions.
67+
Hosts must define ``PluginSlot`` components in areas of the UI where they intend to accept extensions.
6368
The Host MFE, and thus the owners of the Host MFE, are responsible for deciding where it is acceptable to mount a plugin.
6469
They also decide the dimensions, responsiveness/scrolling policy, and whether the slot supports passing any additional
6570
data to the plugin as part of its contract.
@@ -92,12 +97,12 @@ Plugin Micro-frontend (JSX) and Fallback Behavior
9297
-------------------------------------------------
9398

9499
The plugin MFE is no different than any other MFE except that it defines a Plugin component as a child of a route.
95-
This component is responsible for communicating (via postMessage) with the host page and resizing its content to match
100+
This component is responsible for communicating (via ``postMessage``) with the host page and resizing its content to match
96101
the dimensions available in the host’s PluginSlot.
97102

98103
It’s notoriously difficult to know in the host application when an iFrame has failed to load.
99104
Because of security sandboxing, the host isn’t allowed to know the HTTP status of the request or to inspect what was
100-
loaded, so we have to rely on waiting for a postMessage event from within the iFrame to know it has successfully loaded.
105+
loaded, so we have to rely on waiting for a ``postMessage`` event from within the iFrame to know it has successfully loaded.
101106
For the fallback content, the Plugin-owning team would pass a fallback component into the Plugin tag that is wrapped around their component, as noted below. Otherwise, a default fallback component would be used.
102107
.. code-block::
103108

src/plugins/Plugin.jsx

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
import { PLUGIN_RESIZE } from './data/constants';
1717
import messages from './Plugins.messages';
1818

19-
// TODO: create example-plugin-app/src/PluginOne.jsx for example of customizing errorFallback
19+
// TODO: create example-plugin-app/src/PluginOne.jsx for example of customizing errorFallback as part of APER-3042 https://2u-internal.atlassian.net/browse/APER-3042
2020
const ErrorFallbackDefault = ({ intl }) => (
2121
<div>
2222
<h2>
@@ -25,9 +25,8 @@ const ErrorFallbackDefault = ({ intl }) => (
2525
</div>
2626
);
2727

28-
// TODO: find out where "ready" comes from
2928
const Plugin = ({
30-
children, className, intl, style, ready, ErrorFallbackComponent,
29+
children, className, style, ready, ErrorFallbackComponent, intl,
3130
}) => {
3231
const [dimensions, setDimensions] = useState({
3332
width: null,
@@ -59,7 +58,8 @@ const Plugin = ({
5958
}, []);
6059

6160
useEffect(() => {
62-
// TODO: find out where "ready" comes from and when it would be true
61+
/** Ready defaults to true, but can be used to defer rendering the Plugin until certain processes have
62+
* occurred or conditions have been met */
6363
if (ready) {
6464
dispatchReadyEvent();
6565
}
@@ -68,8 +68,6 @@ const Plugin = ({
6868
return (
6969
<div className={className} style={finalStyle}>
7070
<ErrorBoundary
71-
// Must be React Component format (<ComponentName ...props />) or it won't render
72-
// TODO: update frontend-platform code to refactor <ErrorBoundary /> or include info in docs somewhere
7371
fallbackComponent={<ErrorFallback intl={intl} />}
7472
>
7573
{children}
@@ -81,12 +79,18 @@ const Plugin = ({
8179
export default injectIntl(Plugin);
8280

8381
Plugin.propTypes = {
82+
/** The content for the Plugin */
8483
children: PropTypes.node.isRequired,
84+
/** Classes to apply to the Plugin wrapper component */
8585
className: PropTypes.string,
86+
/** Custom error fallback component */
8687
ErrorFallbackComponent: PropTypes.func,
87-
intl: intlShape.isRequired,
88+
/** If ready is true, it will render the Plugin */
8889
ready: PropTypes.bool,
89-
style: PropTypes.object, // eslint-disable-line
90+
/** Styles to apply to the Plugin wrapper component */
91+
style: PropTypes.shape({}),
92+
/** i18n */
93+
intl: intlShape.isRequired,
9094
};
9195

9296
Plugin.defaultProps = {

src/plugins/Plugin.test.jsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ describe('PluginContainer', () => {
6161
// Ensure the iframe has the proper attributes
6262
expect(iframeElement.attributes.getNamedItem('allow').value).toEqual(IFRAME_FEATURE_POLICY);
6363
expect(iframeElement.attributes.getNamedItem('src').value).toEqual(iframeConfig.url);
64-
expect(iframeElement.attributes.getNamedItem('scrolling').value).toEqual('auto');
6564
expect(iframeElement.attributes.getNamedItem('title').value).toEqual(title);
6665
// The component isn't ready, since the class has 'd-none'
6766
expect(iframeElement.attributes.getNamedItem('class').value).toEqual('border border-0 w-100 d-none');

src/plugins/PluginContainer.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ const PluginContainer = ({ config, ...props }) => {
3535
export default PluginContainer;
3636

3737
PluginContainer.propTypes = {
38+
/** Configuration for the Plugin in this container — i.e pluginSlot[id].example_plugin */
3839
config: pluginConfigShape,
3940
};
4041

src/plugins/PluginContainerIframe.jsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ const PluginContainerIframe = ({
3535
config, fallback, className, ...props
3636
}) => {
3737
const { url } = config;
38-
const { title, scrolling } = props;
38+
const { title } = props;
3939
const [mounted, setMounted] = useState(false);
4040
const [ready, setReady] = useState(false);
4141

@@ -68,7 +68,6 @@ const PluginContainerIframe = ({
6868
title={title}
6969
src={url}
7070
allow={IFRAME_FEATURE_POLICY}
71-
scrolling={scrolling}
7271
referrerPolicy="origin" // The sent referrer will be limited to the origin of the referring page: its scheme, host, and port.
7372
className={classNames(
7473
'border border-0 w-100',
@@ -85,17 +84,19 @@ const PluginContainerIframe = ({
8584
export default PluginContainerIframe;
8685

8786
PluginContainerIframe.propTypes = {
87+
/** Configuration for the Plugin in this container — i.e pluginSlot[id].example_plugin */
8888
config: pluginConfigShape,
89+
/** Custom fallback component used when component is not ready (i.e. "loading") */
8990
fallback: PropTypes.node,
90-
scrolling: PropTypes.oneOf(['auto', 'yes', 'no']),
91+
/** Accessible label for the iframe */
9192
title: PropTypes.string,
93+
/** Classes to apply to the iframe */
9294
className: PropTypes.string,
9395
};
9496

9597
PluginContainerIframe.defaultProps = {
9698
config: null,
9799
fallback: null,
98-
scrolling: 'auto',
99100
title: null,
100101
className: null,
101102
};

src/plugins/PluginSlot.jsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import PluginContainer from './PluginContainer';
1616
const PluginSlot = forwardRef(({
1717
as, id, intl, pluginProps, children, ...props
1818
}, ref) => {
19+
/** TODO: Examples still need to be set up as part of APER-3042 https://2u-internal.atlassian.net/browse/APER-3042 */
1920
/* the plugins below are obtained by the id passed into PluginSlot by the Host MFE. See example/src/PluginsPage.jsx
2021
for an example of how PluginSlot is populated, and example/src/index.jsx for a dummy JS config that holds all plugins
2122
*/
@@ -62,10 +63,15 @@ const PluginSlot = forwardRef(({
6263
export default injectIntl(PluginSlot);
6364

6465
PluginSlot.propTypes = {
66+
/** Element type for the PluginSlot wrapper component */
6567
as: PropTypes.elementType,
68+
/** Default content for the PluginSlot */
6669
children: PropTypes.node,
70+
/** ID of the PluginSlot configuration */
6771
id: PropTypes.string.isRequired,
72+
/** i18n */
6873
intl: intlShape.isRequired,
74+
/** Props that are passed down to each Plugin in the Slot */
6975
pluginProps: PropTypes.object, // eslint-disable-line
7076
};
7177

src/plugins/data/hooks.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ import { PLUGIN_MOUNTED, PLUGIN_READY, PLUGIN_UNMOUNTED } from './constants';
1515
* @returns {Object} - JS configuration for the PluginSlot
1616
*/
1717
export function usePluginSlot(id) {
18-
if (getConfig().plugins[id] !== undefined) {
19-
return getConfig().plugins[id];
18+
if (getConfig().pluginSlots[id] !== undefined) {
19+
return getConfig().pluginSlots[id];
2020
}
2121
return { keepDefault: true, plugins: [] };
2222
}

0 commit comments

Comments
 (0)