Using the PnP PropertyFieldGrid Control in an SPFx Web Part
The PropertyFieldGrid control adds a selectable grid to the SPFx Property Pane. Each row can display an icon, title, and description, while supporting single or multiple selection.
In this example, the Property Pane displays four sample files. The selected items are stored in the Web Part properties and then rendered by the React component.
This article is part of the PnP SPFx controls roadmap.
Official documentation
PropertyFieldGrid — PnP SPFx Property Controls
The official example defines an IItem[] collection and passes it to PropertyFieldGrid inside the Property Pane groupFields. (PNP GitHub)
Install the dependency
Run the following command inside the current SPFx solution:
npm install @pnp/spfx-property-controls --save
The example also uses a Fluent UI icon:
npm install @fluentui/react-icons --save
Then restore the project dependencies:
npm install
Important note for version 3.24.0
In @pnp/spfx-property-controls version 3.24.0, IItem may not be exported directly from the public PropertyFieldGrid entry point.
Use separate imports:
import { PropertyFieldGrid} from '@pnp/spfx-property-controls/lib/PropertyFieldGrid';import { IItem} from '@pnp/spfx-property-controls/lib/propertyFields/propertyFieldGrid/grid/IItem';
The official documentation currently shows both imports coming from the same module, but the separate internal import is required by the installed package structure in this project. (PNP GitHub)
Web Part properties interface
The Web Part stores the description and the selected grid items:
export interface IPropertyFieldGridWpWebPartProps { description: string; gridItems: IItem[];}
The gridItems property contains the items selected by the user in the Property Pane.
React component properties
File:
src/webparts/propertyFieldGridWp/components/IPropertyFieldGridWpProps.ts
import { IItem} from '@pnp/spfx-property-controls/lib/propertyFields/propertyFieldGrid/grid/IItem';export interface IPropertyFieldGridWpProps { description: string; isDarkTheme: boolean; environmentMessage: string; userDisplayName: string; gridItems: IItem[];}
The same IItem type is used by both the Web Part and the React component.
Define the available grid items
Import the Fluent UI icon:
import { DocumentBulletListRegular} from '@fluentui/react-icons';
Create the item collection:
const gridItems: IItem[] = [ { key: '1', icon: React.createElement(DocumentBulletListRegular), title: 'File 1', description: 'This is the first document' }, { key: '2', icon: React.createElement(DocumentBulletListRegular), title: 'File 2', description: 'This is the second document' }, { key: '3', icon: React.createElement(DocumentBulletListRegular), title: 'File 3', description: 'This is the third document' }, { key: '4', icon: React.createElement(DocumentBulletListRegular), title: 'File 4', description: 'This is the fourth document' }];
Each item contains:
keyicontitledescription
The key must uniquely identify the item.
Initialize the selected items
During Web Part initialization, ensure that gridItems is always an array:
protected onInit(): Promise<void> { return this._getEnvironmentMessage() .then((message: string) => { this._environmentMessage = message; if (!this.properties.gridItems) { this.properties.gridItems = []; } });}
This prevents errors when the Web Part is added for the first time and no items have been selected.
Pass the selected items to React
Inside the Web Part render() method:
public render(): void { const element: React.ReactElement<IPropertyFieldGridWpProps> = React.createElement( PropertyFieldGridWp, { description: this.properties.description, isDarkTheme: this._isDarkTheme, environmentMessage: this._environmentMessage, userDisplayName: this.context.pageContext.user.displayName, gridItems: this.properties.gridItems || [] } ); ReactDom.render(element, this.domElement);}
The selected Property Pane values are passed through:
gridItems: this.properties.gridItems || []
The fallback avoids calling .map() on an undefined value.
Add PropertyFieldGrid to the Property Pane
The control must be added to the groupFields collection:
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration { return { pages: [ { header: { description: strings.PropertyPaneDescription }, groups: [ { groupName: strings.BasicGroupName, groupFields: [ PropertyPaneTextField( 'description', { label: strings.DescriptionFieldLabel } ), PropertyFieldGrid( 'gridItems', { key: 'gridFieldId', label: 'Grid Items', items: gridItems, multiSelect: true, defaultSelectedItems: this.properties.gridItems || [], maxHeight: 500, className: 'gridClass', isVisible: true, column1Label: 'File', column2Label: 'Description', onSelected: ( selectedItems: IItem[] ): void => { this.properties.gridItems = selectedItems; this.render(); console.log( 'Selected grid items:', selectedItems ); } } ) ] } ] } ] };}
The official control supports properties such as items, multiSelect, defaultSelectedItems, maxHeight, column labels, visibility, styles, and the onSelected callback. (PNP GitHub)
Property Pane group
The native PropertyPaneTextField and the PnP PropertyFieldGrid are placed inside the same Property Pane group:
groups: [ { groupName: strings.BasicGroupName, groupFields: [ PropertyPaneTextField(...), PropertyFieldGrid(...) ] }]
The group controls the organization of the Property Pane. The grid is one field inside that group.
Important PropertyFieldGrid settings
Enable multiple selection
multiSelect: true
This allows the user to select more than one grid item.
For single selection:
multiSelect: false
Available items
items: gridItems
This collection contains every row displayed by the control.
Restore selected items
defaultSelectedItems: this.properties.gridItems || []
This restores the saved selection whenever the Property Pane is reopened.
Handle selection
onSelected: ( selectedItems: IItem[]): void => { this.properties.gridItems = selectedItems; this.render();}
The selected items are saved in the Web Part property and the React component is rendered again.
Grid headers
column1Label: 'File',column2Label: 'Description'
These properties define the labels displayed at the top of the grid.
React component
File:
src/webparts/propertyFieldGridWp/components/PropertyFieldGridWp.tsx
import * as React from 'react';import { IPropertyFieldGridWpProps} from './IPropertyFieldGridWpProps';const PropertyFieldGridWp: React.FC<IPropertyFieldGridWpProps> = (props) => { return ( <div> <h2>{props.description}</h2> <p> Welcome, {props.userDisplayName}! </p> <p> Environment: {props.environmentMessage} </p> <p> Dark Theme: {' '} {props.isDarkTheme ? 'Yes' : 'No'} </p> <h3>Selected items</h3> {props.gridItems.length === 0 ? ( <p>No items selected.</p> ) : ( <ul> {props.gridItems.map(item => ( <li key={item.key}> {item.icon} {' '} <strong>{item.title}</strong> {': '} {item.description} </li> ))} </ul> )} </div> );};export default PropertyFieldGridWp;
The component uses .map() to render the selected items:
props.gridItems.map(item => ( <li key={item.key}> {item.icon} {' '} {item.title} {': '} {item.description} </li>))
The empty-state condition improves the initial experience:
props.gridItems.length === 0
Data flow
The complete flow is:
Available IItem[] collection ↓PropertyFieldGrid ↓User selects rows ↓onSelected() ↓this.properties.gridItems ↓React component props ↓Selected items rendered in the Web Part
The Property Pane controls the selection, the Web Part stores it, and the React component displays it.
Run the project
heft start
Open the Web Part in the SharePoint Workbench, edit its properties, and select one or more grid rows.
The selected files will appear in the Web Part content.
Conclusion
PropertyFieldGrid is useful when a Property Pane must present a visual collection of selectable items instead of a standard dropdown or checkbox list.
This example demonstrates:
- creating an
IItem[]collection; - displaying icons, titles, and descriptions;
- enabling multiple selection;
- storing selected items in Web Part properties;
- passing the selection to a React component;
- rendering the selected items in the Web Part.
Official documentation:
https://pnp.github.io/sp-dev-fx-property-controls/controls/PropertyFieldGrid/
