Templating is a pretty powerful approach to provide extensibility to a project/component/library. It can be used to deliver different behaviors and/or look and feel to different customers, or provide extendable open-source libraries.
There are a lot of template libraries out there that can be used in your project. One of the most popular is Handlebars.js. The problem with these libraries is that in most cases they provide you an ability to define "static" content (basically, HTML and CSS). And if you want to include some actionable content (e.g. handle events from outside the template, etc.) - it might be either tricky or impossible.
In the next several blog posts I want to showcase how to create fully functional React templates (with props, events handling etc.) and dynamically load them using new SharePoint Framework project type - Library Component.
Technically, this approach can be exposed to non-SPFx projects as well, but it is not the purpose of this blog posts series.
If you don't want to read the posts - the code is available here. Feel free to use it in any way you want.
Second post - Implementation
ObjectiveSo, as mentioned above, templating allows us to provide extensibility to existing projects and implement different behaviors and look and feel for different customers separately of the core component.
In these posts we'll be implementing a Tasks List web part that shows a list of tasks and selected task details.
We want the web part to have some default UI and also allow to provide custom templates for the components.
Default UI will look like that:
And alternative UI:
Initial Implementation DetailsFrom components perspective we'll have
- Task - to display a single task item in the list
- Tasks List - to display a collection of tasks
- Task Details - to display details of the selected task
As we're going to have different implementations of the same components in different projects/libraries we also need to define "contracts" - interfaces and naming conventions that must be used in all implementations. It will allow to dynamically load elements and "know" what classes/functions/etc. we can use.
Here are the common interfaces and types we need:
- TemplateType - type to define all possible templates: task-list, task, task-details
- ITask - interface to define Task properties
- ITaskListProps - TaskList React component's props
- ITaskProps - Task React component's props
- ITaskDetailsProps - TaskDetails React component's props
- ITemplateFactory - Templates Factory interface, main entry point for templates libraries.
React Dynamic ComponentsReact by its nature allows to use dynamic components names right in JSX and TSX files - any tag name starting with Capital letter will compile in createComponent method call. So, you can have something like:
In our case we can use React dynamic components (or dynamic tag names) and ITemplateFactory interface to render needed component with dynamic template:
SharePoint Framework Library ComponentsThe last but not least part of the puzzle is SPFx Library Components.
From the official documentation: Library component type enables you to have independently versioned and deployed code, which is served automatically for the SharePoint Framework components with a deployment through app catalog. Library component provides you alternative option to create shared code, which can be then used and referenced cross all the components in the tenant. You can think of Library Components as DLLs - separate packages that can be included (statically or dynamically) to other projects. And that is a great fit for our needs.
Note: current latest version of SharePoint Framework is 1.8.2. Library Components feature is in preview and is subject to change. It is not currently supported for use in production environments.
So, we can (and will) use Library Component to implement alternative rendering for our tasks list and task details, and dynamically load that library by the web part.
Next StepsThe next post walks you through the whole implementation, including Templates library loader, default Template Factory, Library Component with alternative templates, and dynamic rendering of tasks list and task details.
That's all for today!