Using PropertyFieldColorPicker in an SPFx Web Part

The PropertyFieldColorPicker control from the PnP SPFx Property Controls library adds a visual color selector to the SharePoint Framework property pane.

Instead of requiring users to manually enter hexadecimal or RGB color values, the control provides an interactive interface for selecting a color.

In this example, the selected color is stored in the web part properties, passed to a React component, displayed as text, and applied as the background color of a preview box.

Install the PnP Property Controls package

From the root folder of the existing SPFx solution, run:

npm install @pnp/spfx-property-controls --save

After installing the package, restore the remaining project dependencies:

npm install

Import the control

Add the following import to the web part file:

import {
PropertyFieldColorPicker,
PropertyFieldColorPickerStyle
} from '@pnp/spfx-property-controls/lib/PropertyFieldColorPicker';

The import provides:

  • PropertyFieldColorPicker: the property pane control.
  • PropertyFieldColorPickerStyle: the enum used to select the visual presentation of the picker.

Define the web part properties

The selected color must be stored in the web part property bag.

export interface IPropertyFieldColorPickerWpWebPartProps {
description: string;
color: string;
}

The color property receives a CSS-compatible color value such as:

#0078d4

Depending on the selected color and alpha configuration, the control may also return values such as:

rgba(0, 120, 212, 0.5)

Configure the property pane

Add the control inside the groupFields collection of the property pane group.

PropertyFieldColorPicker('color', {
label: 'Color',
selectedColor: this.properties.color,
onPropertyChange: this.onPropertyPaneFieldChanged,
properties: this.properties,
disabled: false,
debounce: 1000,
isHidden: false,
alphaSliderHidden: false,
style: PropertyFieldColorPickerStyle.Full,
iconName: 'Precipitation',
key: 'colorFieldId'
})

The first argument, 'color', must match the property declared in the web part properties interface.

color: string;

When the user selects a new color, the control updates:

this.properties.color

Understanding the configuration

label

Defines the label displayed above the control.

label: 'Color'

selectedColor

Connects the current web part property value to the control.

selectedColor: this.properties.color

onPropertyChange

Uses the standard SPFx property pane change handler.

onPropertyChange: this.onPropertyPaneFieldChanged

This allows SPFx to update the property bag and refresh the web part.

properties

Provides the complete web part properties object to the PnP control.

properties: this.properties

disabled

Controls whether the color picker can be edited.

disabled: false

debounce

Defines the delay, in milliseconds, before the new value is applied.

debounce: 1000

In this example, the control waits one second before updating the property.

isHidden

Controls the visibility of the property pane field.

isHidden: false

alphaSliderHidden

Controls whether the transparency slider is displayed.

alphaSliderHidden: false

Because the value is false, the user can select colors with transparency.

Use the following configuration to hide the transparency slider:

alphaSliderHidden: true

style

Defines how the control is displayed.

style: PropertyFieldColorPickerStyle.Full

The official control supports two styles:

PropertyFieldColorPickerStyle.Full

Displays the complete color picker directly in the property pane.

PropertyFieldColorPickerStyle.Inline

Displays a compact control that opens the picker when activated.

iconName

Defines the Fluent UI icon used by the inline version of the control.

iconName: 'Precipitation'

This property is mainly relevant when using:

PropertyFieldColorPickerStyle.Inline

key

Provides a unique identity for the property pane control.

key: 'colorFieldId'

Each custom property pane control should have a unique key.

Complete web part file

import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version } from '@microsoft/sp-core-library';
import {
type IPropertyPaneConfiguration,
PropertyPaneTextField
} from '@microsoft/sp-property-pane';
import {
BaseClientSideWebPart
} from '@microsoft/sp-webpart-base';
import {
IReadonlyTheme
} from '@microsoft/sp-component-base';
import * as strings from 'PropertyFieldColorPickerWpWebPartStrings';
import PropertyFieldColorPickerWp
from './components/PropertyFieldColorPickerWp';
import {
IPropertyFieldColorPickerWpProps
} from './components/IPropertyFieldColorPickerWpProps';
import {
PropertyFieldColorPicker,
PropertyFieldColorPickerStyle
} from '@pnp/spfx-property-controls/lib/PropertyFieldColorPicker';
export interface IPropertyFieldColorPickerWpWebPartProps {
description: string;
color: string;
}
export default class PropertyFieldColorPickerWpWebPart
extends BaseClientSideWebPart<IPropertyFieldColorPickerWpWebPartProps> {
private _isDarkTheme: boolean = false;
private _environmentMessage: string = '';
public render(): void {
const element: React.ReactElement<IPropertyFieldColorPickerWpProps> =
React.createElement(
PropertyFieldColorPickerWp,
{
description: this.properties.description,
isDarkTheme: this._isDarkTheme,
environmentMessage: this._environmentMessage,
userDisplayName: this.context.pageContext.user.displayName,
color: this.properties.color || '#ffffff'
}
);
ReactDom.render(element, this.domElement);
}
protected onInit(): Promise<void> {
return this._getEnvironmentMessage().then((message: string) => {
this._environmentMessage = message;
});
}
private _getEnvironmentMessage(): Promise<string> {
if (this.context.sdks.microsoftTeams) {
return this.context.sdks.microsoftTeams.teamsJs.app
.getContext()
.then(context => {
switch (context.app.host.name) {
case 'Office':
return this.context.isServedFromLocalhost
? strings.AppLocalEnvironmentOffice
: strings.AppOfficeEnvironment;
case 'Outlook':
return this.context.isServedFromLocalhost
? strings.AppLocalEnvironmentOutlook
: strings.AppOutlookEnvironment;
case 'Teams':
case 'TeamsModern':
return this.context.isServedFromLocalhost
? strings.AppLocalEnvironmentTeams
: strings.AppTeamsTabEnvironment;
default:
return strings.UnknownEnvironment;
}
});
}
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: [
PropertyPaneTextField('description', {
label: strings.DescriptionFieldLabel
}),
PropertyFieldColorPicker('color', {
label: 'Color',
selectedColor:
this.properties.color || '#ffffff',
onPropertyChange:
this.onPropertyPaneFieldChanged,
properties: this.properties,
disabled: false,
debounce: 1000,
isHidden: false,
alphaSliderHidden: false,
style:
PropertyFieldColorPickerStyle.Full,
iconName: 'Precipitation',
key: 'colorFieldId'
})
]
}
]
}
]
};
}
}

A default value is also used in the property pane:

selectedColor: this.properties.color || '#ffffff'

This keeps the picker and the React component synchronized when the web part is added for the first time.

React properties interface

Create or update:

src/webparts/propertyFieldColorPickerWp/components/IPropertyFieldColorPickerWpProps.ts
export interface IPropertyFieldColorPickerWpProps {
description: string;
isDarkTheme: boolean;
environmentMessage: string;
userDisplayName: string;
color: string;
}

The color property receives the value selected in the property pane.

React component

Create or update:

src/webparts/propertyFieldColorPickerWp/components/PropertyFieldColorPickerWp.tsx
import * as React from 'react';
import {
IPropertyFieldColorPickerWpProps
} from './IPropertyFieldColorPickerWpProps';
const PropertyFieldColorPickerWp:
React.FunctionComponent<IPropertyFieldColorPickerWpProps> =
(props) => {
const previewStyle: React.CSSProperties = {
backgroundColor: props.color,
width: '100px',
height: '100px',
border: '1px solid #8a8886'
};
return (
<div>
<h1>Property Field Color Picker Web Part</h1>
<p>
This sample demonstrates the use of the
PropertyFieldColorPicker control.
</p>
<p>
Description: {props.description}
</p>
<p>
User Display Name: {props.userDisplayName}
</p>
<p>
Environment Message: {props.environmentMessage}
</p>
<p>
Is Dark Theme: {props.isDarkTheme ? 'Yes' : 'No'}
</p>
<p>
Selected Color: {props.color}
</p>
<div
style={previewStyle}
role="img"
aria-label={`Selected color preview: ${props.color}`}
/>
</div>
);
};
export default PropertyFieldColorPickerWp;

The selected color is applied directly to the preview element:

backgroundColor: props.color

Because the control returns a CSS-compatible value by default, no conversion is required before using it in a React inline style.

Property flow

The complete property flow is:

PropertyFieldColorPicker
this.properties.color
React.createElement(...)
props.color
backgroundColor

The property pane stores the value:

this.properties.color

The web part passes it to React:

color: this.properties.color || '#ffffff'

The component receives it:

props.color

Finally, the value is used as a CSS color:

backgroundColor: props.color

Returning an IColor object

By default, the control returns a CSS-compatible string.

For advanced scenarios, the control can return a Fluent UI IColor object by enabling:

valueAsObject: true

The property type must then be changed from string to IColor.

Example:

import {
IColor
} from '@fluentui/react';
export interface IPropertyFieldColorPickerWpWebPartProps {
color: IColor;
}

The returned object provides information such as:

color.str
color.hex
color.r
color.g
color.b
color.h
color.s
color.v

For this demonstration, a string is sufficient because the selected value is applied directly to CSS.

Run the web part

Start the local development server using Heft:

heft start

Add the web part to the SharePoint workbench, open the property pane, and select a color.

The preview square should update using the selected value.

Conclusion

The PropertyFieldColorPicker provides a simple and user-friendly way to configure colors in an SPFx web part.

The control integrates with the standard SPFx property bag and can return either:

  • A CSS-compatible color string.
  • A complete Fluent UI IColor object.

For common styling scenarios, the default string value can be applied directly to React inline styles, CSS variables, borders, backgrounds, icons, or text colors.

Official documentation

PnP SPFx Property Controls — PropertyFieldColorPicker:

Edvaldo Guimrães Filho Avatar

Published by