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.strcolor.hexcolor.rcolor.gcolor.bcolor.hcolor.scolor.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
IColorobject.
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:
