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

Introduction
 
In this article, you will learn the basics of creating a custom pane property definition. This helps with adding pane properties to the web part property panes using web part files.
 
In my previous articles, you can learn about adding existing properties to SPFx web part properties pane.
So far, you have seen only adding/using property templates available on open source. Now, you will learn developing and inserting custom pane properties to the properties pane.
 
The custom field property declared in the web part file (under getPropertyPaneConfiguration method) contains target property name and other custom properties.
  1. PropertyFieldMessageBar('targetpropname', customprops)  
In the below sections, you will see in detail about the pane property definition for the custom pane property declared above.
 
Interfaces Available
 
Microsoft provides two interfaces for creating custom property.
  • IPropertyPaneCustomFieldProps

    This interface provides key properties and methods that help in developing the pane property. Properties and methods available are the following.

    • context
    • key
    • onDispose() and 
    • onRender()

  • IPropertyPaneField

    This interface provides a few properties that can be inherited for defining the custom pane property (fields).

    • properties
    • shouldFocus
    • targetProperty - Property name
    • type - Type of property (custom, text, dropdown, etc.)
Developing the Property Definition File
 
The property definition is written as a function which inherits data from class and interface components. Here, a custom interface is introduced to input the user defined custom properties. The properties like label, on property change method and other internal properties are defined here.
 
The following code snippet shows the sample custom interface defined to input from the user. Likewise, any other properties can be defined.
  1. interface IPropertyFieldMessageBarProps {  
  2.   label: string;  
  3.   onPropertyChange(propertyPath: string, oldValue: any, newValue: any): void;  
  4.   properties: any;  
  5.   key?: string;  
  6. }   
Note - The values are declared and passed when the property is declared in the getPropertyPaneConfiguration method of the web part file.
 
Then another interface is defined which inherits properties from IPropertyPaneCustomFieldProps. This is an internal interface that contains all the properties and methods, which will not be exposed to users or the web part file. This can, in turn, hold the properties collection (created using previous interface IPropertyFieldMessageBarProps) as one property.
 
The following snapshot shows the sample internal interface, which is not exposed to users or web part file.
  1. interface IPropertyFieldMessageBarPropsInternal extends IPropertyPaneCustomFieldProps {  
  2.   label: string;   
  3.   targetProperty: string;  
  4.   onRender(elem: HTMLElement): void// Method to render data (in this case reactjs is used)  
  5.   onDispose(elem: HTMLElement): void// Method to delete the object  
  6.   onPropertyChange(propertyPath: string, oldValue: any, newValue: any): void;  
  7.   properties: any; // set of properties (holds values of property collection defined using IPropertyFieldMessageBarProps)  
  8.   key: string;  
  9. }   
Then, the class is defined, which contains the variables, constructor, and render method. The class inherits properties from other interfaces, like IPropertyPaneField and IPropertyFieldMessageBarPropsInternal (custom). 
  • The constructor is used to initialize the variables.
  • The render method will display the data. The custom function or the react components are used for rendering the data.
The following code snippet shows the property definition class file.
  1. export class PropertyFieldMessageBarBuilder implements IPropertyPaneField<IPropertyFieldMessageBarPropsInternal> {  
  2.   
  3.   //Properties defined by IPropertyPaneField  
  4.   public properties: IPropertyFieldMessageBarPropsInternal;  
  5.   public targetProperty: string;  
  6.   public type: PropertyPaneFieldType = PropertyPaneFieldType.Custom;  
  7.   
  8.   //Custom properties  
  9.   private label: string;  
  10.   private onPropertyChange: (propertyPath: string, oldValue: any, newValue: any) => void;  
  11.   private customProperties: any;  
  12.   private key: string;  
  13.     
  14.   // Initializes the varialbes or methods  
  15.   public constructor(usertargetProperty: string, userproperties: IPropertyFieldMessageBarPropsInternal) {  
  16.     this.render = this.render.bind(this);  
  17.     this.targetProperty = userproperties.targetProperty;  
  18.     this.properties = userproperties;  
  19.     this.label = userproperties.label;  
  20.     this.properties.onDispose = this.dispose;  
  21.     this.properties.onRender = this.render;  
  22.     this.onPropertyChange = userproperties.onPropertyChange;  
  23.     this.customProperties = userproperties.properties;  
  24.     this.key = userproperties.key;  
  25.   }  
  26.   
  27.   // Renders the data  
  28.   private render(elem: HTMLElement): void {  
  29.       
  30.   }  
  31.   
  32. }   
Then, the custom function is defined, which can then be declared in the web part files. From the web part file, the required properties are passed as input. 
  1. export function PropertyPaneMessageBar(targetProperty: string, properties: IPropertyFieldMessageBarProps): IPropertyPaneField<IPropertyFieldMessageBarPropsInternal> {  
  2.   
  3.     // Builds the property based on the custom data  
  4.     var newProperties: IPropertyFieldMessageBarPropsInternal = {  
  5.       label: properties.label,  
  6.       targetProperty: targetProperty,  
  7.       onPropertyChange: properties.onPropertyChange,  
  8.       properties: properties.properties,  
  9.       onDispose: null,  
  10.       onRender: null,  
  11.       key: properties.key  
  12.     };  
  13.       
  14.     // Initialize and render the properties  
  15.     return new PropertyFieldMessageBarBuilder(targetProperty, newProperties);  
  16. }   
Reference
 
More such custom pane properties are developed and available directly for use under github site. These properties templates are available, which can be readily declared in the web part files (getPropertyPaneConfiguration method). 
 
Summary
 
Thus you have learned the basic understanding of developing custom pane property which can be added to property panes. The interfaces, class, and functions are used for defining the data. The rendering can be done on the same file or using react components.
 
What Next
 
In the next article, you will see the full sample which defines the pane property, renders the property using react components, and invokes the pane property from the web part file.