Plugin Templates

Copy-pastable example snippets for accelerating plugin development

Method of a component

In this example - render

const render = (args, callback, instance) => (
<>
{ callback.apply(instance, args) }
</>
);
export default {
'Component/NAME/Component': {
'member-function': {
render
}
}
};

Container functions

Common case - when you need to pass an additional function from parent to child

export class NAMEContainerPlugin {
containerFunctions = (originalMember, instance) => ({
...originalMember,
handleSomething: this.handleSomething.bind(instance)
});
handleSomething(arg) {
console.log(arg);
}
}
const { containerFunctions } = new NAMEContainerPlugin();
export default {
'Component/NAME/Container': {
'member-property': {
containerFunctions
}
}
};

Prop types

You need to add an additional prop to propTypes after passing an additional prop to the component? No problem!

import PropTypes from 'prop-types';
const propTypes = (originalMember) => ({
...originalMember,
handleSomething: PropTypes.func.isRequired
});
export default {
'Component/NAME/Component': {
'static-member': {
propTypes
}
}
};

Default props

Not required new propType - do this.

const defaultProps = (originalMember) => ({
...originalMember,
pluginProp: 'PluginProp'
});
export default {
'Component/NAME/Container': {
'static-member': {
defaultProps
}
}
};

More state

Additional fields for the state.

const state = (originalMember) => ({
...originalMember,
PluginState: 'PluginState'
});
export default {
'Component/NAME/Container': {
'member-property': {
state
}
}
};

Adding a Reducer to the Redux Store

Add reducers to the application as follows.

import { NAMEReducer } from '../store/NAME;
const getStaticReducers = (args, callback, instance) => ({
...callback(...args),
NAMEReducer
});
export const config = {
'Store/Index/getReducers': {
function: getStaticReducers
}
};
export default config;

Query fields

Additional query field shown below!

const _getMETHODFields = (args, callback, instance) => [
...callback.apply(instance, args),
'field_name'
];
export default {
'Query/NAME': {
'member-function': {
_getMETHODFields
}
}
};

mapStateToProps

Connect an additional piece of state to the component

const mapStateToProps = (args, callback, instance) => {
const [state] = args;
return {
...callback(...args),
pluginProp: state.SomeReducer.someState
};
};
export default {
'Component/NAME/Container/mapStateToProps': {
function: mapStateToProps
}
};

mapDispatchToProps

Connect an additional dispatch function to the component

const { letsDoSomething } = import('Store/STORENAME/STORENAME.action');
const mapDispatchToProps = (args, callback, instance) => {
const [dispatch] = args;
return {
...callback(...args),
doSomething: (value) => dispatch(letsDoSomething(value))
};
};
export default {
'Component/NAME/Container/mapDispatchToProps': {
function: mapDispatchToProps
}
};

Adding a Route to the Router

Note how we use async import(...) statement here in order to optimize bundle sizes!

import { lazy } from 'react';
import { Route } from 'react-router-dom';
import { withStoreRegex } from 'Component/Router/Router.component';
export const YourPage = lazy(() => import(
/* webpackMode: "lazy", webpackChunkName: "extension-name" */
'../route/YourPage'
));
const SWITCH_ITEMS_TYPE = (originalMember) => [
...originalMember,
{
component: (
<Route
path={ withStoreRegex('/path') }
render={ (props) => <YourPage { ...props } /> }
/>
),
position: 100
}
];
export const config = {
'Component/Router/Component': {
'member-property': {
SWITCH_ITEMS_TYPE
}
}
};
export default config;

Extending maps

Example: creating a new tab in MyAccount

import { lazy } from 'react';
import {
MY_TAB_PATH,
MY_TAB_NAME
} from '../component/MyAccountCustomTab/MyAccountCustomTab.config';
import MyAccountCustomTab from '../component/MyAccountCustomTab';
const renderMap = (originalMember) => ({
[MY_TAB_NAME]: MyAccountCustomTab,
...originalMember,
});
const tabMap = (originalMember) => ({
...originalMember,
[MY_TAB_NAME]: {
url: `/${ MY_TAB_PATH }`,
name: __('My Tab')
}
});
export default {
'Route/MyAccount/Container': {
'static-member': {
tabMap
}
},
'Route/MyAccount/Component': {
'member-property': {
renderMap
}
}
};