Understanding SPFx Web Part Property Pane

1+

In traditional SharePoint Webparts can be configured using properties or webpart properties where as in modern SharePoint or SPFX client-side web parts they are referred as property panes. These property panes control behavior and appearance of the webpart including metadata like Pages, Header, Groups or property fields.

Field Object
Label PropertyPaneLabel
Textbox PropertyPaneTextField
Multiple lines of text PropertyPaneTextField
Link PropertyPaneLink
Dropdown PropertyPaneDropdown
Checkbox PropertyPaneCheckbox
Choice PropertyPaneChoiceGroup
Toggle PropertyPaneToggle
Slider PropertyPaneSlider
Button PropertyPaneButton
Horizontal Rule PropertyPaneHorizontalRule
Custom Our own implementation using combination of above

To analyze code, follow my previous post “helloworld spfx solution”. Once yeoman generator scaffolds the project

Open file HelloWorldWebPart.ts located at \src\webparts\helloworld.

The method getPropertyPaneConfiguration() contains the configuration to build the property pane.

protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
    return {
      pages: [
        {
          header: {
            description: strings.PropertyPaneDescription
          },
          groups: [
            {
              groupName: strings.BasicGroupName,
              groupFields: [
                PropertyPaneTextField('description', {
                  label: strings.DescriptionFieldLabel
                })
              ]
            }
          ]
        }
      ]
    };
  }

The default class “HelloWorldWebPart” accepts property type of interface “IHelloWorldWebPartProps”, which by default has description property of type string.

export default class HelloWorldWebPart extends BaseClientSideWebPart<IHelloWorldWebPartProps> {

  public render(): void {
    this.domElement.innerHTML = `
      <div class="${ styles.helloWorld }">
        <div class="${ styles.container }">
          <div class="${ styles.row }">
            <div class="${ styles.column }">
              <span class="${ styles.title }">Welcome to SharePoint!</span>
              <p class="${ styles.subTitle }">Customize SharePoint experiences using Web Parts.</p>
              <p class="${ styles.description }">${escape(this.properties.description)}</p>
              <a href="https://aka.ms/spfx" class="${ styles.button }">
                <span class="${ styles.label }">Learn more</span>
              </a>
            </div>
          </div>
        </div>
      </div>`;
  }

export interface IHelloWorldWebPartProps {
  description: string;
}

Property types are defined in import section from ‘@microsoft/sp-webpart-base’ & used in render() method as below.

import {
  BaseClientSideWebPart,
  IPropertyPaneConfiguration,
  PropertyPaneTextField
} from '@microsoft/sp-webpart-base';

${escape(this.properties.description)}

Now let us add multiple properties as specified in table above to enhance solution

Steps to add new properties:

  • Import related types objects
  • Add new properties in Interface property pane webpartprops & map related fields to typed objects
  • Add multiple pages, header, groups & new property pane fields and map to related typed objects in getPropertyPaneConfiguration method
  • Modify render method to show selected field values
  • Finally, gulp serve to Test property pane in local workbench & add webpart. 

Step 1 – Import related types objects

import {
  BaseClientSideWebPart,
  IPropertyPaneConfiguration,
  PropertyPaneLabel, //Label
  PropertyPaneTextField, //Textbox
  PropertyPaneLink, //Link
  PropertyPaneDropdown, //Dropdown
  PropertyPaneCheckbox, //Checkbox
  PropertyPaneChoiceGroup, //Choice
  PropertyPaneToggle, //Toggle
  PropertyPaneSlider, //Slider
  PropertyPaneButton, //Button
  PropertyPaneHorizontalRule, //HorizontalRule
} from '@microsoft/sp-webpart-base';

Step 2 – Add new properties in Interface property pane webpartprops & map related fields to typed objects

export interface IHelloWorldWebPartProps {
  name: string;
  description: string;
  url: string;
  dropdown: string;
  checkbox: string;
  choice: string;
  toggle: string;
  slider: string;
  button: string;
  horizontalrule: string;
}

Step 3 – Add multiple pages, header, groups & new property pane fields and map to related typed objects in getPropertyPaneConfiguration method

protected TextBoxValidationMethod(value: string): string{
    if(value.length <= 4) {return "Name should be at least 5 charecters."}
    else { return ''; }
  }

protected ButtonClick(val: any): any{
    this.properties.name = "Button Click Succeeded";
    return "test";
  }

protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
    return {
      pages: [
        {
          header: {
            description: "Property Pane Page 1 - Name, Description, Label and Link"
          },
          groups: [
            {
              groupName: "Property Pane Group 1 Page 1", 
              groupFields: [
                PropertyPaneTextField('name', {
                  label: "Name",
                  multiline:false,
                  resizable:false,
                  onGetErrorMessage:this.TextBoxValidationMethod,
                  errorMessage:"This is error message for Name",
                  deferredValidationTime:10000,
                  placeholder:"Please enter name",
                  "description": "Name property pane field"
                }),
                PropertyPaneTextField('description', {
                  label: "Description",
                  multiline: true,
                  resizable:true,
                  placeholder:"Please enter description",
                  "description": "Description property pane field"
                }),
                PropertyPaneLabel('label', {
                  text:"Please enter text",
                  required:true
                }),
                PropertyPaneTextField("textlabel",{}),
                PropertyPaneLink('url', {
                  href: 'http://VarunAtluri.com',
                  text: "Varun Atluri's blog",
                  target: '_blank',
                  popupWindowProps: {
                    height: 500,
                    width: 500,
                    positionWindowPosition: 2,
                    title: "Varun Atluri's blog"
                  }
              })
              ]
            }
          ]
        },
        {
          header: {
            description: "Property Pane Page 2 - Dropdown, Checkbox and choice"
          },
          groups: [
            {
              groupName: "Property Pane Group 1 Page 2", 
              groupFields: [
                PropertyPaneDropdown('dropdown', {
                  label: "Drop Down",
                  options:[
                    {key: 'Drop Down 1', text:'Drop Down 1'},
                    {key: 'Drop Down 2', text:'Drop Down 2'},
                    {key: 'Drop Down 3', text:'Drop Down 3'}
                  ],
                  selectedKey: 'Drop Down 2'
                }),
                PropertyPaneCheckbox('checkbox', {
                  text: "Yes/No",
                  checked:true,
                  disabled:false
                }),
              ]
            },
            {
              groupName: "Property Pane Group 2 Page 2", 
              groupFields: [
                PropertyPaneChoiceGroup('choice', {
                  label: 'Choices',
                  options: [
                    { key: 'Choice 1', text: 'Choice 1' },
                    { key: 'Choice 2', text: 'Choice 2', checked: true },
                    { key: 'Choice 3', text: 'Choice 3' }
                  ]
                })
              ]
            }
          ]
        },
        {
          header: {
            description: "Property Pane Page 3 - slider, toggle, button and Horizontal rule" 
          },
          groups: [
            {
              groupName: "Property Pane Group 1 Page 3", 
              groupFields: [
                PropertyPaneSlider('slider', {
                  label: "Slider",
                  min:1,
                  max:5
                }),
                PropertyPaneToggle('toggle', {
                  label: "Slider",
                })
              ]
            },
            {
              groupName: "Property Pane Group 2 Page 3", 
              groupFields: [
                PropertyPaneButton('Button', {
                  text: "Normal button",
                  buttonType: PropertyPaneButtonType.Normal,
                  onClick: this.ButtonClick.bind(this)
                 }),
                 PropertyPaneHorizontalRule(),
              ]
            }
          ]
        }
      ]
    };
  }

Step 4 – Modify render method to show selected field values

public render(): void {
    this.domElement.innerHTML = `
      <div class="${ styles.helloWorld }">
        <div class="${ styles.container }">
          <div class="${ styles.row }">
            <div class="${ styles.column }">
              <span class="${ styles.title }">Welcome to SharePoint!</span>
              <p class="${ styles.subTitle }">Customize SharePoint experiences using Web Parts.</p>

              <p class="${ styles.description }">Name : ${escape(this.properties.name)}</p>
              <p class="${ styles.description }">Description : ${escape(this.properties.description)}</p>
              <p class="${ styles.description }">Textlabel : ${escape(this.properties.textlabel)}</p>
              <p class="${ styles.description }">url : ${escape(this.properties.url)}</p>

              <p class="${ styles.description }">horizontalrule : ${escape(this.properties.horizontalrule)}</p>

              <p class="${ styles.description }">dropdown : ${escape(this.properties.dropdown)}</p>
              <p class="${ styles.description }">checkbox : ${escape(this.properties.checkbox)}</p>
              <p class="${ styles.description }">choice : ${escape(this.properties.choice)}</p>

              <p class="${ styles.description }">horizontalrule : ${escape(this.properties.horizontalrule)}</p>

              <p class="${ styles.description }">slider : ${escape(this.properties.slider)}</p>
              <p class="${ styles.description }">toggle : ${escape(this.properties.toggle)}</p>

              <p class="${ styles.description }">button : ${escape(this.properties.button)}</p>
              <p class="${ styles.description }">horizontalrule : ${escape(this.properties.horizontalrule)}</p>

              <a href="https://aka.ms/spfx" class="${ styles.button }">
                <span class="${ styles.label }">Learn more</span>
              </a>
            </div>
          </div>
        </div>
      </div>`;
  }

Step 5 –  gulp serve to Test property pane in local workbench & add webpart

Edit webpart to add property pane field values

Click next for property page 2 fields

Click next for property page 3 fields

Reactive vs Non-Reactive property pane

Framework supports immediate changes to render when a page editor changes the property pane value. This is called Reactive property pane and vice versa is called Non-reactive property pane.

To disable the behavior of reactive property pane by adding below code to webpart class

protected get disableReactivePropertyChanges(): boolean {
  return true;
}

Now let’s check more in detail about properties for each property pane typed object 

Text box (PropertyPaneTextField) Properties:

Property Description
label Label shown next to the control.
description Description shown next to the control.
value Value in the field can be used to set default text.
ariaLabel A non-visible label
multiline (boolean) Specifies whether the textbox is multiline.
placeholder Allows you to provide default placeholder text, shown when the control has no value.
resizable Specifies whether the control can be enlarged by the user
underlined Whether or not the textfield is underlined.
errorMessage A static value for the error message
onGetErrorMessage Pointer to function to use for validation – returns either a string for simple cases OR a Promise<string> for more complex cases where you need to make an async call to SharePoint to do the validation.
deferredValidationTime Amount of time (milliseconds) to wait before showing the validation error message

Checkbox (PropertyPaneCheckbox) Properties:

Property Description
text Text displayed next to the checkbox.
checked Specifies if the control is checked.
disabled Specifies if the control is disabled.

Dropdown (PropertyPaneDropdown) Properties:

Property Description
label Label displayed next to the control.
options An array of IPropertyPaneDropdownOption objects
selectedKey Key name of the selected item. Can be used to set the initially selected item.
disabled Specifies if the control is *disabled*

Choice Group control (PropertyPaneChoiceGroup) Properties:

This control allows user to make a selection, but with radio button instead of dropdown list. Here we can also use images instead of plain radio buttons

Property Description
label Label displayed next to the control.
options An array of IPropertyPaneChoiceOption objects
Property Description
Key Unique key of the item
text option value text
imageSrc Source image url
imageSize Object size – Width, height properties using json format
selectedImageSrc Selected source image url
Checked Used to specify if this item is selected
Disabled Specifies if this item is disabled

Link control (PropertyPaneLink) Properties:

Property Description
text Text for the link.
href Hyperlink destination.
target Window to use – options include _self (default), _parent, _top and _blank.
popupWindowProps An object specifying the width, height, title and position of a pop-up window (IPopupWindowProps).
disabled Specifies if the link is disabled.

Slider control (PropertyPaneSlider) Properties:

Property Description
label Text displayed next to the control.
min Specifies the minimum value (lower bound).
max Specifies the maximum value (upper bound).
step Specifies the increment that the value can be increased by when the slider is dragged or clicked.
showValue If the current value should be shown next to the control.
value Specifies the initial value.
disabled Specifies if the control is disabled.

Toggle control (PropertyPaneToggle) Properties:

Property Description
label Text displayed next to the control.
onText Specifies the text to show when in the ‘on’ state.
offText Specifies the text to show when in the ‘off’ state.
checked Used to set the state of the toggle.
key A unique key to identify the control.
disabled Specifies if the control is disabled.

Buttons (PropertyPaneButton) Properties:

Property Description
text Text displayed on the button.
buttonType Specifies the type of button to show, from PropertyPaneButtonType enum:
Normal
Primary
Hero
Compound
Command
Icon
onClick Pointer to a function to execute when button is clicked.
icon Used for Hero and Icon buttons only. (Office UI Fabric icon set)
description Used for Compund buttons only – displays as the secondary text
disabled Specifies if the control is disabled.

1+

You may also like

Leave a Reply

Your email address will not be published.