Adding Custom Properties To SPFx Web Part Properties Pane - Part Two

Introduction
 
In this article, you will learn how to define and add custom properties to SPFx eb part properties pane.
 
In my previous previous article, you will have gained a basic understanding of developing custom pane property.
In this article, you will see the custom pane property definition, React components to render the property and property declaration in the Web part file. In the sample, you will learn how to define and render the message bar as property pane in SPFx Web part properties pane.
 
In SPFx project, create a folder to hold the property definition file and React component file.
 
 
 
Property Definition File
 
Import interfaces/objects

Import the necessary data/objects from Cloud, other modules or other files. Here, React files from React module, custom properties from the Web part module and custom interface from custom React file are being imported.
 
Interfaces

Lets see the interfaces defined.
  • IPropertyFieldMessageBarProps.
  • IPropertyFieldMessageBarPropsInternal: IPropertyFieldMessageBarPropsInternal interface inherits from. IPropertyPaneCustomFieldProps interface. Custom interface is defined (IPropertyFieldMessageBarPropsInternal), which inherits the properties/methods from the standard interface (IPropertyPaneCustomFieldProps).
Class

Then the class is defined. The class holds the private and public variables, constructor, render and other custom methods defined.
 
Function

Then the function is defined. The function builds the property required for rendering the data. The property collection is created using the internal interface created above. And then the class is instantiated, which in turn calls the render method. (Remember Render method invokes React file methods to display the data.)
 
The code snippet given below shows the property definition file. Some components use export component, since those components are referred in the other files/sections.
  1. import * as React from 'react';  
  2. import * as ReactDom from 'react-dom';  
  3.   
  4. import PropertyFieldMessageBarHost from '../spfxcustomproperties/spfxcustomprop';  
  5.   
  6. import {  
  7.   IPropertyPaneCustomFieldProps,  
  8.   IPropertyPaneField,  
  9.   PropertyPaneFieldType  
  10. } from '@microsoft/sp-webpart-base';  
  11.   
  12. export interface IPropertyFieldMessageBarProps {  
  13.   label: string;  
  14.   onPropertyChange(propertyPath: string, oldValue: any, newValue: any): void;  
  15.   properties: any;  
  16.   key?: string;  
  17. }  
  18.   
  19. export interface IPropertyFieldMessageBarPropsInternal extends IPropertyPaneCustomFieldProps {  
  20.   label: string;   
  21.   targetProperty: string;  
  22.   onRender(elem: HTMLElement): void// Method to render data (in this case reactjs is used)  
  23.   onDispose(elem: HTMLElement): void// Method to delete the object  
  24.   onPropertyChange(propertyPath: string, oldValue: any, newValue: any): void;  
  25.   properties: any; // set of properties (holds values of property collection defined using IPropertyFieldMessageBarProps)  
  26.   key: string;  
  27. }  
  28.   
  29. export class PropertyFieldMessageBarBuilder implements IPropertyPaneField<IPropertyFieldMessageBarPropsInternal> {  
  30.   
  31.   //Properties defined by IPropertyPaneField  
  32.   public properties: IPropertyFieldMessageBarPropsInternal;  
  33.   public targetProperty: string;  
  34.   public type: PropertyPaneFieldType = PropertyPaneFieldType.Custom;  
  35.   
  36.   //Custom properties  
  37.   private label: string;  
  38.   private onPropertyChange: (propertyPath: string, oldValue: any, newValue: any) => void;  
  39.   private customProperties: any;  
  40.   private key: string;  
  41.     
  42.   // Initializes the varialbes or methods  
  43.   public constructor(usertargetProperty: string, userproperties: IPropertyFieldMessageBarPropsInternal) {  
  44.     this.render = this.render.bind(this);  
  45.     this.targetProperty = userproperties.targetProperty;  
  46.     this.properties = userproperties;  
  47.     this.label = userproperties.label;  
  48.     this.properties.onDispose = this.dispose;  
  49.     this.properties.onRender = this.render;  
  50.     this.onPropertyChange = userproperties.onPropertyChange;  
  51.     this.customProperties = userproperties.properties;  
  52.     this.key = userproperties.key;  
  53.   }  
  54.   
  55.   // Renders the data  
  56.   private render(elem: HTMLElement): void {  
  57.     const element: React.ReactElement<IPropertyFieldMessageBarPropsInternal> = React.createElement(PropertyFieldMessageBarHost, {  
  58.       label: this.label,  
  59.       targetProperty: this.targetProperty,  
  60.       onDispose: null,  
  61.       onRender: null,  
  62.       onPropertyChange: this.onPropertyChange,  
  63.       properties: this.customProperties,  
  64.       key: this.key  
  65.     });  
  66.       
  67.     ReactDom.render(element, elem);  
  68.   }  
  69.   
  70.   private dispose(elem: HTMLElement): void {  
  71.   
  72.   }  
  73.   
  74. }  
  75.   
  76. export function PropertyPaneMessageBar(targetProperty: string, properties: IPropertyFieldMessageBarProps): IPropertyPaneField<IPropertyFieldMessageBarPropsInternal> {  
  77.   
  78.     // Builds the property based on the custom data  
  79.     var newProperties: IPropertyFieldMessageBarPropsInternal = {  
  80.       label: properties.label,  
  81.       targetProperty: targetProperty,  
  82.       onPropertyChange: properties.onPropertyChange,  
  83.       properties: properties.properties,  
  84.       onDispose: null,  
  85.       onRender: null,  
  86.       key: properties.key  
  87.     };  
  88.       
  89.     // Initialize and render the properties  
  90.     return new PropertyFieldMessageBarBuilder(targetProperty, newProperties);  
  91. }   
React file For Rendering
 
Import interfaces/objects
  • Import the necessary objects/interfaces. 
  • The internal interface created in the definition file are being imported. 
  • Import the React message bar component from the office site.
Class

Define the class file, which has constructor and Render method to create and display the message bar element with the custom message.
 
The code snippet given below shows React file code to render the pane property on SPFx properties pane.
  1. import * as React from 'react';  
  2. import { IPropertyFieldMessageBarPropsInternal } from './spfxpropdefinition';  
  3.   
  4. import { MessageBar,MessageBarType} from 'office-ui-fabric-react/lib/MessageBar';  
  5.   
  6. export default class PropertyFieldMessageBarHost extends React.Component<IPropertyFieldMessageBarPropsInternal, {}> {  
  7.   
  8.   constructor(props: IPropertyFieldMessageBarPropsInternal) {  
  9.     super(props);  
  10.       
  11.   }  
  12.   
  13.   public render(): JSX.Element {  
  14.     return (  
  15.       <div>          
  16.            <MessageBar ref="alert" messageBarType={ MessageBarType.info } >{this.props.label}</MessageBar>  
  17.       </div>  
  18.     );  
  19.   }  
  20. }   
Web part file
 
From the default Web part file available, import the message bar property from the property definition file and then declare the message bar property inside the getPropertyPaneConfiguration() method.
 
The code snippet given below shows how property definition is being imported.
  1. import {PropertyPaneMessageBar} from './spfxcustomproperties/spfxpropdefinition';   
The code snippet given below shows the Web part property definition in the Web parts file.
  1. protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {  
  2.   return {  
  3.     pages: [  
  4.       {  
  5.         header: {  
  6.           description: strings.PropertyPaneDescription  
  7.         },  
  8.         groups: [  
  9.           {  
  10.             groupName: strings.BasicGroupName,  
  11.             groupFields: [  
  12.                 
  13.               PropertyPaneMessageBar('msgbar',{  
  14.                 label:"Message to be displayed on SPfx properties pane",  
  15.                 onPropertyChange: this.onPropertyPaneFieldChanged,  
  16.                 properties: this.properties  // other user defined props                                  
  17.               })  
  18.                 
  19.             ]  
  20.           }  
  21.         ]  
  22.       }  
  23.     ]  
  24.   };  
  25. }   
Run/Deploy the project
 
The screenshot given below shows the Web part with the message bar property.
 
Summary
 
Thus, you have learned about developing/defining SPFx custom pane property and adding it to the SPFx Web part properties pane.
 
To Learn More
 
In my previous articles, you can learn about adding the existing properties to SPFx Web part properties pane