PnP Modern Search Extensibility: Creating Web Components
In the last couple of blogs we looked at basics of PnP Modern Search Extensibility and how to add a custom layout, in this blog we will look at how to extend PnP Modern Search webparts by adding custom web components.
A Web component is a set of web platform
APIs that allow you to create new custom, reusable, encapsulated HTML elements that
can be used in your templates to implement complex behaviors. In this solution
we use them here as "wrappers" for React components
to be able to use them with Handlebars.
In the previous blog, we used <pnp-collapsible> built in web component, here is the complete list of built-in web components provided by PnP,
- <pnp-iconfile>
- <pnp-documentcard>
- <pnp-filepreview>
- <pnp-icon>
- <pnp-panel>
- <pnp-collapsible>
- <pnp-img>
- <pnp-breadcrumb>
- Create and register a custom persona web component based on PersonaWebComponent.
- Create and register a custom web component for hover card based on mgt-person-card.
- Create a custom layout class, corresponding HTML template and register the custom layout to make it available.
How to create a Web component
Creation process consists of two steps:
- Create the web component logic and any sub components.
- Register the web component in the library class.
Create the web component logic and any sub components
To Create the Custom Persona web component we need to,
- A web component class that would implement BaseWebComponent. This class must at least have connectedCallback() implemented, which essentially loads our React Component (CustomPersonaComponent here). The resolveAttributes() method will look at all data-* HTML attributes in your web component custom element node and return a corresponding key/value pair object with values in their guessed type that you can pass directly to your React component as props.
- A React component,
- The react component in our case is going to extend functionality of default PersonaWebComponent used by PnP Search and will also capture the Profile Page url and Pronouns properties passed to it from the handlebar template, so we will start with copying code for PersonaWebComponent (available at pnp-modern-search-extensibility\pnp-modern-search-main\search-parts\src\components\PersonaComponent.tsx).
- We will change the class names for props, state and component classes to ICustomPersonaComponentProps, ICustomPersonaComponenState and CustomPersonaComponent respectively.
- We will add pronouns and profilePageUrl props to our ICustomPersonalComponentProps
- We will then make changes to onRenderPrimaryText method implementation to include pronouns beside the user display name and then we will add a <Link> around <Persona> and pass the profilePageUrl along with user’s email address.
To create a Custom Persona Card Component we need to,
- Similar to Custom Persona component we will create a web component class that would implement BaseWebComponent. This class must at least have connectedCallback() implemented. In addition to that, this class will also initialize the SPHttpClient and PageContext (available through BaseWebComponent) objects for us and pass them as additional props to the React component.
- In the React component,
- This component will get the
user’s pronouns and assistant email passed through Handlebar Layout (in turn
passed through Web Component props) along with SPHttpClient and PageContext.
- In the SharePoint User profile the assistant field only stores the email property of the user selected, we will have resolve the email address to a display name using a REST API call on componentDidMount().
Register the web component in the library class
To register the components in the library, we will override the getCustomWebComponents() and add details for both of these components.
Creating handlebar layout
To Create the Custom People handlebar
layout we need to,
- We will create the custom-people.html and CustomPeopleLayout.ts files
- The custom-people.html is based on people.html form PnP package but we are going to lock down the people fields that means that the user won’t get following layout options but we do want to ask user for Profile Page url, so we will be adding that as an layout option,
- In the following screenshot,
- When configuring <mgt-person> declaration we are saying person-card should appear on hover (person-card=”hover”)
- When configuring <custom-persona> we are locking down the card size to be extra large (data-persona-size=”15”). As image, display name etc. fields are no longer configurable we are passing their values using layout slots expressions. We also pass value of Profile Page url layout option that we just configured. We also expect that a managed property would have been configured for user's pronouns and would have been added as a layout slot so, we also pass it using the layout slot expression.
- Lastly, we want our own custom person card <custom-person-card> to appear on hover, so, we declare that inside <template data-type=”person-card”> and we pass assistant email and pronouns as well.
- We simplify the CustomPeopleLayout.ts
file to following,
- The only step that remains is
to register Custom-People handlebar inside getCustomLayouts() method,
Comments
Post a Comment