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:

key
icon
title
description

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/

Edvaldo Guimrães Filho Avatar

Published by