Skip to main content

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.

warning

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;
}
warning

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
}
warning

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.