SPFx Property Pane Checkbox: Showing and Hiding Content in a Web Part

Introduction

In this article, we will explore one of the simplest and most useful controls available in the SharePoint Framework Property Pane: the PropertyPaneCheckbox.

The goal is simple:

Allow the user to decide whether the web part title should be displayed or hidden.

import {
type IPropertyPaneConfiguration,
PropertyPaneCheckbox
} from ‘@microsoft/sp-property-pane’;

  • show or hide a title;
  • enable or disable a feature;
  • show or hide a section;
  • activate or deactivate a layout option.

import {
type IPropertyPaneConfiguration,
PropertyPaneCheckbox
} from ‘@microsoft/sp-property-pane’;


What We Are Building

We will create a web part with one property:

showTitle: boolean;

When the checkbox is checked, the title appears.

When the checkbox is unchecked, the title is hidden.

The flow is:

PropertyPaneCheckbox
this.properties.showTitle
React props
Conditional rendering

The React Component

The React component receives a boolean property called showTitle.

import * as React from 'react';
export interface IPropertyPaneCheckboxProps {
showTitle: boolean;
}
const PropertyPaneCheckboxCtr: React.FC<IPropertyPaneCheckboxProps> = (props) => {
return (
<div>
{props.showTitle && (
<h1>Property Pane Checkbox</h1>
)}
<p>showTitle: {props.showTitle.toString()}</p>
</div>
);
}
export default PropertyPaneCheckboxCtr;

The most important part is this block:

{props.showTitle && (
<h1>Property Pane Checkbox</h1>
)}

This is called conditional rendering in React.

It means:

If props.showTitle is true, render the <h1>.
If props.showTitle is false, render nothing.

This is a very clean way to show or hide parts of the UI.


The Web Part Property

The web part needs to store the value selected by the user in the Property Pane.

In this example, the property is:

showTitle: boolean;

In your current code, you are using:

export default class PropertyPaneCheckboxWebPart
extends BaseClientSideWebPart<IPropertyPaneCheckboxProps> {

For learning purposes, this works. However, in larger projects, I recommend separating the web part properties from the React component properties.

For example:

export interface IPropertyPaneCheckboxWebPartProps {
showTitle: boolean;
}

Then the web part would extend:

export default class PropertyPaneCheckboxWebPart
extends BaseClientSideWebPart<IPropertyPaneCheckboxWebPartProps> {

This keeps the responsibilities clearer:

  • Web Part Props: configuration stored by SharePoint.
  • React Props: values passed to the React component.

Passing the Property to React

Inside the render() method, the value stored in the web part is passed to the React component.

public render(): void {
const element: React.ReactElement<IPropertyPaneCheckboxProps> =
React.createElement(
PropertyPaneCheckboxCtr,
{
showTitle: this.properties.showTitle
}
);
ReactDom.render(element, this.domElement);
}

This line is the bridge:

showTitle: this.properties.showTitle

The left side:

showTitle:

is the prop that React will receive.

The right side:

this.properties.showTitle

is the value stored by SPFx.

So the meaning is:

Pass the value from the SPFx property bag to the React component.


Creating the Checkbox in the Property Pane

The checkbox is created inside getPropertyPaneConfiguration().

protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
return {
pages: [
{
header: {
description: strings.PropertyPaneDescription
},
groups: [
{
groupName: strings.BasicGroupName,
groupFields: [
PropertyPaneCheckbox('showTitle', {
text: 'Show Title'
})
]
}
]
}
]
};
}

The key part is:

PropertyPaneCheckbox('showTitle', {
text: 'Show Title'
})

The string 'showTitle' is not random.

It is the name of the property that SPFx will update.

In practice, when the user checks or unchecks the checkbox, SPFx updates:

this.properties.showTitle

That is the connection between the Property Pane and the web part.


Why the Initial Value Can Be Undefined

When a web part is added to a page for the first time, SharePoint may not have any saved value yet.

So this property:

this.properties.showTitle

can initially be:

undefined

This is why it is useful to define a default value.

In your code, you did this in onInit():

protected onInit(): Promise<void> {
this.properties.showTitle ??= true;
return this._getEnvironmentMessage().then(message => {
this._environmentMessage = message;
});
}

This line:

this.properties.showTitle ??= true;

means:

If showTitle is null or undefined, set it to true.

This is useful because the web part starts with the title visible by default.

After the user changes the value, SharePoint stores the selected value.


Full Web Part Example

import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version } from '@microsoft/sp-core-library';
import {
type IPropertyPaneConfiguration,
PropertyPaneCheckbox
} from '@microsoft/sp-property-pane';
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
import { IReadonlyTheme } from '@microsoft/sp-component-base';
import * as strings from 'PropertyPaneCheckboxWebPartStrings';
import PropertyPaneCheckboxCtr from './components/PropertyPaneCheckbox';
import { IPropertyPaneCheckboxProps } from './components/IPropertyPaneCheckboxProps';
export default class PropertyPaneCheckboxWebPart
extends BaseClientSideWebPart<IPropertyPaneCheckboxProps> {
private _isDarkTheme: boolean = false;
private _environmentMessage: string = '';
public render(): void {
const element: React.ReactElement<IPropertyPaneCheckboxProps> =
React.createElement(
PropertyPaneCheckboxCtr,
{
showTitle: this.properties.showTitle
}
);
ReactDom.render(element, this.domElement);
}
protected onInit(): Promise<void> {
this.properties.showTitle ??= true;
return this._getEnvironmentMessage().then(message => {
this._environmentMessage = message;
});
}
private _getEnvironmentMessage(): Promise<string> {
if (!!this.context.sdks.microsoftTeams) {
return this.context.sdks.microsoftTeams.teamsJs.app.getContext()
.then(context => {
let environmentMessage: string = '';
switch (context.app.host.name) {
case 'Office':
environmentMessage = this.context.isServedFromLocalhost
? strings.AppLocalEnvironmentOffice
: strings.AppOfficeEnvironment;
break;
case 'Outlook':
environmentMessage = this.context.isServedFromLocalhost
? strings.AppLocalEnvironmentOutlook
: strings.AppOutlookEnvironment;
break;
case 'Teams':
case 'TeamsModern':
environmentMessage = this.context.isServedFromLocalhost
? strings.AppLocalEnvironmentTeams
: strings.AppTeamsTabEnvironment;
break;
default:
environmentMessage = strings.UnknownEnvironment;
}
return environmentMessage;
});
}
return Promise.resolve(
this.context.isServedFromLocalhost
? strings.AppLocalEnvironmentSharePoint
: strings.AppSharePointEnvironment
);
}
protected onThemeChanged(currentTheme: IReadonlyTheme | undefined): void {
if (!currentTheme) {
return;
}
this._isDarkTheme = !!currentTheme.isInverted;
const {
semanticColors
} = currentTheme;
if (semanticColors) {
this.domElement.style.setProperty('--bodyText', semanticColors.bodyText || null);
this.domElement.style.setProperty('--link', semanticColors.link || null);
this.domElement.style.setProperty('--linkHovered', semanticColors.linkHovered || null);
}
}
protected onDispose(): void {
ReactDom.unmountComponentAtNode(this.domElement);
}
protected get dataVersion(): Version {
return Version.parse('1.0');
}
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
return {
pages: [
{
header: {
description: strings.PropertyPaneDescription
},
groups: [
{
groupName: strings.BasicGroupName,
groupFields: [
PropertyPaneCheckbox('showTitle', {
text: 'Show Title'
})
]
}
]
}
]
};
}
}

A Small Improvement

In the original code, the imports were split like this:

import {
type IPropertyPaneConfiguration,
PropertyPaneTextField
} from '@microsoft/sp-property-pane';
import { PropertyPaneCheckbox } from '@microsoft/sp-property-pane';

Since PropertyPaneTextField is not being used in this example, the cleaner version is:

import {
type IPropertyPaneConfiguration,
PropertyPaneCheckbox
} from '@microsoft/sp-property-pane';

This keeps the file cleaner and avoids unused imports.


Why This Example Matters

This example may look simple, but it teaches an important SPFx pattern:

User changes a Property Pane field
SPFx updates this.properties
The web part render method runs again
React receives new props
The UI changes

This same pattern is used with more advanced controls such as:

  • dropdowns;
  • sliders;
  • toggles;
  • choice groups;
  • PnP People Picker;
  • PnP List Picker;
  • PnP Term Picker;
  • PnP Color Picker.

Once you understand the checkbox, you understand the basic idea behind every configurable SPFx web part.


Conclusion

The PropertyPaneCheckbox is one of the simplest controls in the SPFx Property Pane, but it is extremely useful.

It is perfect for boolean configuration scenarios, especially when you need to enable, disable, show, or hide something in your web part.

In this example, we used it to control the visibility of a title. The user changes the checkbox, SPFx stores the value in this.properties.showTitle, and the React component uses conditional rendering to decide whether the title should appear.

This is a fundamental pattern for building configurable SharePoint Framework web parts.


References

SharePoint Framework overview:
https://learn.microsoft.com/en-us/sharepoint/dev/spfx/sharepoint-framework-overview

Integrate web part with the Property Pane:
https://learn.microsoft.com/en-us/sharepoint/dev/spfx/web-parts/basics/integrate-with-property-pane

Microsoft Learn module about SPFx Property Panes:
https://learn.microsoft.com/en-us/training/modules/sharepoint-spfx-web-part-property-pane/

Build custom Property Pane controls:
https://learn.microsoft.com/en-us/sharepoint/dev/spfx/web-parts/guidance/build-custom-property-pane-controls

React conditional rendering:
https://react.dev/learn/conditional-rendering

PnP SPFx React Controls:
https://pnp.github.io/sp-dev-fx-controls-react/

Edvaldo Guimrães Filho Avatar

Published by