Extending Civet
DataProvider
The main place for bringing your own functionality to Civet is the DataProvider
.
You can simply add your own functionality to it by extending the class and then accessing it from within a Resource
or from somewhere else.
However, this might not be sufficient in all cases, for example if your custom functionality requires the use of React hooks or if you want to extend the ResourceContext
.
If this is the case, you can use DataProvider
's extend
method.
This method is called when initialising the DataProvider
and provides an API for registering various plugins.
Please note that the extend
method is called by the DataProvider
's constructor, so probably before your own constructor's logic is executed.
There are currently two types of plugins which can be registered using the extend
function, context plugins and UI plugins.
They are both used to extend the ResourceContext
but differ in where they can be used and what you can accomplish with them.
class MyDataProvider extends DataProvider {
extend(extend) {
super.extend(extend);
// Register a context plugin
extend.context(useMyContextPlugin);
// Register a UI plugin
extend.ui(MyUIPlugin);
}
// ...
}
Context plugins
Context plugins are React hooks for extending the ResourceContext
.
They work for both the Resource
component and the useResource
hook.
As these plugins are handled as React hooks, they may use React hooks (for example useMemo
) themselves.
Context plugins cannot render any content.
Context plugins are handled in the order they are registered, always before UI plugins.
Their signature is:
/**
* @param {object} context - the ResourceContext to be modified
* @param {props} context - custom props passed to useResource or Resource
* @returns the modified memoized ResourceContext
**/
function useMyContextPlugin(context, props) {
return context;
}
The context returned by a context plugin must be memoized, for example by using React's useMemo
hook.
UI plugins
UI plugins are React components for extending the ResourceContext
.
They only work for the Resource
component and are ignored for the useResource
hook.
You can use UI plugins to render additional content.
UI plugins are handled in the order they are registered, always after context plugins.
Their signature is:
function MyUIPlugin({ ...props, context, children }) {
// UI plugins must always render the result of the children function.
// The children function takes the (un)modified context as its only argument.
return children(context);
}
MyUIPlugin.propTypes = {
props: PropTypes.object, // custom props passed to Resource
context: PropTypes.object, // the ResourceContext to be modified
children: PropTypes.func, // render props function to pass the modified memoized context down
}
The context passed down by a UI plugin must be memoized, for example by using React's useMemo
hook.
DataProvider plugins
You can bundle related functionality in standalone plugin functions in order to make them reusable by others.
The createPlugin
function creates a plugin that can simply be called on an existing DataProvider
implementation.
You can then extend it like described above in the DataProvider section.