In this tutorial, we will learn how to use the Fluent UI React SwatchColorPicker control in a SharePoint Framework (SPFx) web part. This control is useful when you want to allow users to choose a color from a set of predefined, branded options. For example, to customize the theme of headers, buttons, or other UI elements, as shown below.

Let’s first see the basic usage of the Fluent UI swatch color picker control in the SPFx web part in the section below, and then we will start implementing the above example.
How to Use Fluent UI SwatchColorPicker in SharePoint Framework (SPFx)
Look at the example below. There are two SwatchColorPicker controls: One for selecting solid colors with a click and the other for previewing gradient colors on hover. The selected or hovered color dynamically updates the background of the buttons.

Before creating the SPFx web part for the swatch color picker control, let’s first understand its properties.
SwatchColorPicker is a Fluent UI React component that displays a grid of color options, like small colored buttons. Users can pick a color by clicking on one. You can customize how they appear and how the app responds to user interaction (such as hover, click, focus, etc.).
<SwatchColorPicker
columnCount={5}
colorCells={[
{ id: 'red', label: 'Red', color: '#ff0000' },
{ id: 'blue', label: 'Blue', color: '#0000ff' },
]}
cellHeight={35}
cellWidth={35}
cellShape={'square'}
aria-labelledby={`${baseId}-custom-size`}
onChange={(e, id, color) => console.log(color)}
/>
Here are some of the properties of the swatch color picker control.
| Property | Type | Description |
|---|---|---|
| columnCount | number | Number of color swatches per row |
| colorCells | array [] | The list of colors to display, each with an ID, label, and color value. |
| cellHeight | number | Height of an individual cell, in pixels. |
| cellWidth | number | The distance between cells, in pixels. |
| cellShape | string | Shape of each swatch (‘circle’ or ‘square’). |
| aria-labelledby | number | Used for accessibility (labeling the picker). |
| onCellHovered | event | A callback function that runs when the user hovers over a color cell. |
| onCellFocused | event | A callback function that runs when the user focuses on a color cell. |
| onRenderColorCellContent | event | Custom render for gradient swatches. |
| onChange | event | A callback function that runs when a color is selected. You get the color chosen here. |
Now, let’s see the steps to create an SPFx web part that uses the Fluent UI swatch color picker control.
- Open the Command Prompt and run the command below. You can also use the Windows Command Prompt or PowerShell Command Prompt.
md SwatchColorPickerSolution
cd SwatchColorPickerSolution
- After this, run the following command:
yo @microsoft/sharepoint
- Now, it will ask you a few details, as shown below. Provide the answers as I have given, or you can change them.
- What is your solution name? swatch-color-picker-solution
- Which type of client-side component to create? WebPart
- Add new Web part to solution swatch-color-picker-solution.
- What is your Web part name? FluentUISwatchColorPicker
- Which template would you like to use? React

Then it will take some time, and the SPFx solution will get created, and you will see a successful message.
- To use the Fluent UI React controls, we need to install the following dependency. Run the below command in the terminal pane of VS Code or in the command prompt itself.
npm install @fluentui/react
- Then, in the .tsx file, import the following statements.
import { IColorCellProps, SwatchColorPicker } from '@fluentui/react/lib/SwatchColorPicker';
import { useId } from '@fluentui/react-hooks';
- By default, the .tsx file contains a class component; now change it to a functional component with the code below.
const FluentUiSwatchColorPicker: React.FC<IFluentUiSwatchColorPickerProps> = (props) => {
const [clickColor, setClickColor] = React.useState<string | undefined>(undefined);
const [hoverColor, setHoverColor] = React.useState<string | undefined>(undefined);
const baseId = useId('colorpicker');
const colorCells = [
{ id: 'a', label: 'Red', color: '#a4262c' },
{ id: 'b', label: 'Orange', color: '#ca5010' },
{ id: 'c', label: 'Yellow', color: '#986f0b' },
{ id: 'd', label: 'Green', color: '#8cbd18' },
{ id: 'e', label: 'Blue', color: '#004e8c' },
];
const gradientColorCells = [
{ id: 'a', label: 'redBlueGradient', color: 'linear-gradient(0, red, blue)' },
{ id: 'b', label: 'greenGradient', color: 'linear-gradient(0, grey, green)' },
{ id: 'c', label: 'yellowGradient', color: 'linear-gradient(0, grey, yellow)' },
{ id: 'd', label: 'magentaGradient', color: 'linear-gradient(0, grey, magenta)' },
{ id: 'e', label: 'cyanGradient', color: 'linear-gradient(0, #038387, #ca5010)' },
{ id: 'f', label: 'ygGradient', color: 'linear-gradient(0, #8cbd18, #69797e)' },
{ id: 'g', label: 'grayGreen', color: 'linear-gradient(0, #0b6a0b, #69797e)' },
{ id: 'h', label: 'gray', color: '#7a7574' },
];
const renderGradientCell = (cellProps: IColorCellProps): JSX.Element => {
return (
<div
style={{
width: '100%',
height: '100%',
borderRadius: '50%',
background: cellProps.color,
}}
/>
);
};
return (
<section className={`${styles.fluentUiSwatchColorPicker}`}>
<h2> Fluent UI SwatchColorPicker Control</h2>
<div id={`${baseId}-swatch`}>Choose a color:</div>
<SwatchColorPicker
columnCount={5}
cellShape='square'
colorCells={colorCells}
cellHeight={35}
cellWidth={35}
aria-labelledby={`${baseId}-swatch`}
onChange={(event, id, color) => {
console.log('Color changed:', id, color);
if (color) {
setClickColor(color); // Save selected color to state
}
}}
/>
<div style={{ display: 'flex', gap: '10px', marginTop: 20 }}>
{['Home', 'New Request', 'All Details'].map((label, index) => (
<button
key={index}
style={{
flex: 1,
padding: '10px',
fontSize: '16px',
background: clickColor || '#0078d4',
color: '#ffffff',
border: 'none',
borderRadius: '5px',
}}
>
{label}
</button>
))}
</div>
<div style={{ marginTop: 40, marginBottom: 10 }}>Choose a gradient (Hover):</div>
<SwatchColorPicker
columnCount={10}
cellShape="circle"
cellHeight={40}
cellWidth={40}
colorCells={gradientColorCells}
aria-labelledby={`${baseId}-hover-swatch`}
onRenderColorCellContent={renderGradientCell}
onCellHovered={(id, color) => setHoverColor(color)}
onCellFocused={(id, color) => setHoverColor(color)}
/>
<div style={{ display: 'flex', gap: 10, marginTop: 20 }}>
{['Home', 'New Request', 'All Details'].map((label, index) => (
<button
key={index}
style={{
flex: 1,
padding: '10px',
fontSize: '16px',
background: hoverColor || '#605e5c',
color: '#ffffff',
border: 'none',
borderRadius: '5px',
}}
>
{label}
</button>
))}
</div>
</section>
);
};
export default FluentUiSwatchColorPicker;
Here:
- FluentUiSwatchColorPicker = An arrow function component.
- clickColor, hoverColor = State variables used to track the selected color using React’s useState.
- setClickColor, setHoverColor = These functions are used to update the states.
- baseId = Used to generate unique IDs within the React functional components.
- colorCells = An array of objects containing the list of solid colors with ID, color name, and color value.
- gradientColorCells = An array of objects containing the list of gradient colors with ID, color name, and color value.
- renderGradientCell() = Custom function for the color cells, because by default, gradient colors are not present, so we are replacing the default cells with gradient color cells.
- In the return() function, we added a SwatchColorPicker that contains solid colors defined in this colorCells array. In the down, three button controls which will change their background color when we click the color in the swatch color picker control.
- I used the map function to create three button controls, as all the styles are the same; only the button text differs. Therefore, I added the button names to an array and applied this map function to create three buttons.
- Another SwatchColorPicker was then added, which contains the gradient colors. So, down again, three different buttons are there, which will change their background color when we hover over the gradient colors.
- Here is the final code in the .tsx file.
import * as React from 'react';
import type { IFluentUiSwatchColorPickerProps } from './IFluentUiSwatchColorPickerProps';
import { useId } from '@fluentui/react-hooks';
import { IColorCellProps, SwatchColorPicker } from '@fluentui/react/lib/SwatchColorPicker';
import styles from './FluentUiSwatchColorPicker.module.scss';
const FluentUiSwatchColorPicker: React.FC<IFluentUiSwatchColorPickerProps> = (props) => {
const [clickColor, setClickColor] = React.useState<string | undefined>(undefined);
const [hoverColor, setHoverColor] = React.useState<string | undefined>(undefined);
const baseId = useId('colorpicker');
const colorCells = [
{ id: 'a', label: 'Red', color: '#a4262c' },
{ id: 'b', label: 'Orange', color: '#ca5010' },
{ id: 'c', label: 'Yellow', color: '#986f0b' },
{ id: 'd', label: 'Green', color: '#8cbd18' },
{ id: 'e', label: 'Blue', color: '#004e8c' },
];
const gradientColorCells = [
{ id: 'a', label: 'redBlueGradient', color: 'linear-gradient(0, red, blue)' },
{ id: 'b', label: 'greenGradient', color: 'linear-gradient(0, grey, green)' },
{ id: 'c', label: 'yellowGradient', color: 'linear-gradient(0, grey, yellow)' },
{ id: 'd', label: 'magentaGradient', color: 'linear-gradient(0, grey, magenta)' },
{ id: 'e', label: 'cyanGradient', color: 'linear-gradient(0, #038387, #ca5010)' },
{ id: 'f', label: 'ygGradient', color: 'linear-gradient(0, #8cbd18, #69797e)' },
{ id: 'g', label: 'grayGreen', color: 'linear-gradient(0, #0b6a0b, #69797e)' },
{ id: 'h', label: 'gray', color: '#7a7574' },
];
const renderGradientCell = (cellProps: IColorCellProps): JSX.Element => {
return (
<div
style={{
width: '100%',
height: '100%',
borderRadius: '50%',
background: cellProps.color,
}}
/>
);
};
return (
<section className={`${styles.fluentUiSwatchColorPicker}`}>
<h2> Fluent UI SwatchColorPicker Control</h2>
<div id={`${baseId}-swatch`}>Choose a color:</div>
<SwatchColorPicker
columnCount={5}
cellShape='square'
colorCells={colorCells}
cellHeight={35}
cellWidth={35}
aria-labelledby={`${baseId}-swatch`}
onChange={(event, id, color) => {
console.log('Color changed:', id, color);
if (color) {
setClickColor(color);
}
}}
/>
<div style={{ display: 'flex', gap: '10px', marginTop: 20 }}>
{['Home', 'New Request', 'All Details'].map((label, index) => (
<button
key={index}
style={{
flex: 1,
padding: '10px',
fontSize: '16px',
background: clickColor || '#0078d4',
color: '#ffffff',
border: 'none',
borderRadius: '5px',
}}
>
{label}
</button>
))}
</div>
<div style={{ marginTop: 40, marginBottom: 10 }}>Choose a gradient (Hover):</div>
<SwatchColorPicker
columnCount={10}
cellShape="circle"
cellHeight={40}
cellWidth={40}
colorCells={gradientColorCells}
aria-labelledby={`${baseId}-hover-swatch`}
onRenderColorCellContent={renderGradientCell}
onCellHovered={(id, color) => setHoverColor(color)}
onCellFocused={(id, color) => setHoverColor(color)}
/>
<div style={{ display: 'flex', gap: 10, marginTop: 20 }}>
{['Home', 'New Request', 'All Details'].map((label, index) => (
<button
key={index}
style={{
flex: 1,
padding: '10px',
fontSize: '16px',
background: hoverColor || '#605e5c',
color: '#ffffff',
border: 'none',
borderRadius: '5px',
}}
>
{label}
</button>
))}
</div>
</section>
);
};
export default FluentUiSwatchColorPicker;
- Once the code is ready, you can run the following command to run the SPFx solution locally.
gulp serve
This will open the local workbench. While the local workbench is running, open the SharePoint workbench and add the web part.
SPFx Fluent UI SwatchColorPicker: Save and Restore Custom Colors in Web Parts
In this section, we will learn how to apply the selected swatch colors to the SPFx web part and save those themes. This way, when we reopen, the previously chosen themes will remain unchanged until the user applies another color.

Let’s understand how this SPFx web part is working:
- The default colors present in the SharePoint list are applied to the SPFx web part initially.
- To apply colors to the header and footer sections, the user must click the color palette icon. It opens the swatch color picker control, allowing them to choose a color.
- Click on the color fill icon to apply gradient colors to buttons in the webpart.
- Clicking the Save Colors button saves the colors, ensuring they remain unchanged even when the web part is reopened.
- Clicking the Reset to Default button will remove the previously saved colors, allowing the default colors to be applied to the web part elements.
Here is the SharePoint list named “ColorSettings,” managing the colors for the SPFx webpart, which has the following fields. Among those fields, only the highlighted fields contain default values, and the remaining two will be autofilled when users click the “Save Colors” button in the web part.

| Column Name | Data Type |
|---|---|
| Title | The default field contains the value “ITEM1” |
| SolidColor | Single line of text |
| DefaultSolidColor | Single line of text [#8bc34a] |
| GradientColor | Single line of text |
| DefaultGradientColor | Single line of text [linear-gradient(90deg,#8bc34a, #558b2f)] |
To achieve this example, create an SPFx webpart by following the steps in the above section. Ensure that you have installed the Fluent UI React library in the solution. Then follow the steps below.
SPFx Solution name = SPFxSwatchColorPickerExample
Web part name = SwatchColorPickerWebpart
Framework = React
- Run the command below in the terminal pane of VS Code or the Windows command prompt.
npm install @pnp/sp --save
This installs the PnP library in your SPFx webpart. To interact with the SharePoint list, we’re using this PnP JS library.
- Once the library is installed, import the following statements into the .ts file located in the src folder, outside of the components folder.
import { spfi, SPFx } from "@pnp/sp";
import { SPFI } from "@pnp/sp";
import "@pnp/sp/webs";
import "@pnp/sp/lists";
import "@pnp/sp/items";
- Then, in the same file, under the export default class, provide this variable creation statement.
private _sp: SPFI;
- Also, update the onInit() method with the below code.
protected onInit(): Promise<void> {
return this._getEnvironmentMessage().then(message => {
this._environmentMessage = message;
this._sp = spfi().using(SPFx(this.context));
});
}
- Update the render() function by adding the sp: this._sp prop into it.
public render(): void {
const element: React.ReactElement<ISwatchColorPickerWebpartProps> = React.createElement(
SwatchColorPickerWebpart,
{
description: this.properties.description,
isDarkTheme: this._isDarkTheme,
environmentMessage: this._environmentMessage,
hasTeamsContext: !!this.context.sdks.microsoftTeams,
userDisplayName: this.context.pageContext.user.displayName,
sp: this._sp
}
);
ReactDom.render(element, this.domElement);
}
This prop passes the configured PnP JS instance to the React component.
- Also, update the Props.ts file code with the code below.
import { SPFI } from '@pnp/sp';
export interface ISwatchColorPickerWebpartProps {
description: string;
isDarkTheme: boolean;
environmentMessage: string;
hasTeamsContext: boolean;
userDisplayName: string;
sp: SPFI
}
- Add the below import statements in the .tsx file located in the components folder.
import { useState, useEffect } from 'react';
import { IColorCellProps, SwatchColorPicker } from '@fluentui/react/lib/SwatchColorPicker';
import { FontIcon } from '@fluentui/react/lib/Icon';
- import { useState, useEffect } from ‘react’; = to use and update states in the React function component.
- import { IColorCellProps, SwatchColorPicker } from ‘@fluentui/react/lib/SwatchColorPicker’; = For using the Swatch color picker control.
- import { FontIcon } from ‘@fluentui/react/lib/Icon’; = For adding color picker icons.
- By default, the React class component will be present; convert it to a functional component by adding the code below.
const SwatchColorPickerWebpart: React.FC<ISwatchColorPickerWebpartProps> = (props) => {
const [clickColor, setClickColor] = useState<string>('');
const [showPicker, setShowPicker] = useState<boolean>(false);
const [gradientColor, setGradientColor] = useState<string>('');
const [showGradientPicker, setShowGradientPicker] = useState<boolean>(false);
const [defaultSolidColor, setDefaultSolidColor] = useState<string>('');
const [defaultGradientColor, setDefaultGradientColor] = useState<string>('');
export default SwatchColorPickerWebpart;
Here,
- SwatchColorPickerWebpart: React.FC<>=() =>{..} = Function component. Within that, we defined some states for the following purposes.
- const [clickColor, setClickColor] = useState<string>(”); = Track the current selected solid color.
- const [showPicker, setShowPicker] = useState<boolean>(false); = Toggle the solid color swatch color picker control popup.
- const [gradientColor, setGradientColor] = useState<string>(”); = Track the current selected gradient color.
- const [showGradientPicker, setShowGradientPicker] = useState<boolean>(false); = Toggle the gradient colorswatch color picker control popup.
- const [defaultSolidColor, setDefaultSolidColor] = useState<string>(”); = From list, hold the default solid color field value.
- const [defaultGradientColor, setDefaultGradientColor] = useState<string>(”); = From list, to hold the default gradient color field value.
- Add the two arrays below to the function component under the states in the .tsx file.
const colorCells = [
{ id: 'darkRed', color: '#a4262c' },
{ id: 'burgundy', color: '#d13438' },
{ id: 'rust', color: '#ca5010' },
{ id: 'goldenrod', color: '#986f0b' },
{ id: 'forestGreen', color: '#498205' },
{ id: 'teal', color: '#007d84' },
{ id: 'darkTeal', color: '#006666' },
{ id: 'blue', color: '#0078d4' },
{ id: 'cornflower', color: '#4f6bed' },
{ id: 'navy', color: '#004e8c' },
{ id: 'indigo', color: '#373277' },
{ id: 'purple', color: '#8764b8' },
{ id: 'magenta', color: '#c239b3' },
{ id: 'gray', color: '#7a7574' },
{ id: 'lightPink1', color: '#f4abba' },
{ id: 'lightPink2', color: '#f79999' },
{ id: 'lightPink3', color: '#f3d6d2' },
{ id: 'peach', color: '#fce100' },
{ id: 'mintGreen', color: '#c7e0c4' },
{ id: 'lightCyan', color: '#b2e0e6' },
{ id: 'aqua', color: '#b2dfdb' },
{ id: 'paleBlue1', color: '#dae8fc' },
{ id: 'paleBlue2', color: '#cfe2f3' },
{ id: 'skyBlue', color: '#9fc5e8' },
{ id: 'lavender', color: '#d9d2e9' },
{ id: 'paleLavender', color: '#cfe2f3' },
{ id: 'lightGray', color: '#e6e6e6' },
];
//Gradient colors for swatch color picker control
const gradientColorCells = [
{ id: 'a', label: 'redBlueGradient', color: 'linear-gradient(0, red, blue)' },
{ id: 'b', label: 'greenGradient', color: 'linear-gradient(0, grey, green)' },
{ id: 'c', label: 'yellowGradient', color: 'linear-gradient(0, grey, yellow)' },
{ id: 'd', label: 'magentaGradient', color: 'linear-gradient(0, grey, magenta)' },
{ id: 'e', label: 'cyanGradient', color: 'linear-gradient(0, #038387, #ca5010)' },
{ id: 'f', label: 'ygGradient', color: 'linear-gradient(0, #8cbd18, #69797e)' },
{ id: 'g', label: 'grayGreen', color: 'linear-gradient(0, #0b6a0b, #69797e)' },
{ id: 'h', label: 'gray', color: '#7a7574' },
];
The above two arrays define the colors used for the solid and gradient Fluent UI swatch color picker controls.
- Add the function below to the arrays in the .tsx file.
const renderGradientCell = (cellProps: IColorCellProps): JSX.Element => {
return (
<div style={{width: '100%',
height: '100%',
borderRadius: '50%',
background: cellProps.color,
}}
/>
)};
This function is used to render gradient-colored cells.
- Add the useEffect() below to the above function within the function component in the .tsx file.
useEffect(() => {const fetchColors = async () => {
try {
const item = await props.sp.web.lists.getByTitle("ColorSettings").items.select("Title", "SolidColor", "GradientColor", "DefaultSolidColor", "DefaultGradientColor").filter(`Title eq 'ITEM1'`)
.top(1)();
if (item.length > 0) {
const data = item[0];
setClickColor(data.SolidColor || data.DefaultSolidColor);
setGradientColor(data.GradientColor || data.DefaultGradientColor);
setDefaultSolidColor(data.DefaultSolidColor);
setDefaultGradientColor(data.DefaultGradientColor);
}
} catch (err) {
console.error("Error fetching list data:", err);
}
};
fetchColors();
}, []);
The above useState() will retrieve the colors from the SharePoint list named “ColorSettings” and set the initial state for the color pickers.
- Add the below function under the useEffect() within the function component of the .tsx file.
const handleSave = async () => {
try {
await props.sp.web.lists.getByTitle("ColorSettings").items.getById(1).update({SolidColor: clickColor,GradientColor: gradientColor});
alert("Colors saved successfully!");
} catch (err) {
console.error("Error saving colors:", err);
}
};
This function I created to save both the swatch color picker control’s selected values to the SharePoint list.
- Add the below function within the function component in the .tsx file.
const handleReset = async () => {
try {
await props.sp.web.lists.getByTitle("ColorSettings").items.getById(1).update({SolidColor: null,GradientColor: null});
setClickColor(defaultSolidColor);
setGradientColor(defaultGradientColor);
alert("Colors reset to default!");
} catch (err) {
console.error("Error resetting colors:", err);
}
};
This function will reset the colors to their default values from the “ColorSettings” list.
- Then add the below return() within the main function component in the .tsx file.
return (
<section className={`${styles.webpartWrapper}`}>
{/* Header section with color pickers */}
<header className={styles.header} style={{ backgroundColor: clickColor || defaultSolidColor }}>
<span>Header Section</span>
<div className={styles.paletteWrapper}>
<FontIcon iconName="Color" className={styles.paletteIcon} title="Choose Solid Color" onClick={() => {setShowPicker(prev => !prev);setShowGradientPicker(false);}}/>
<FontIcon iconName="BackgroundColor" className={styles.paletteIcon} title="Choose Gradient Color" onClick={() => {setShowGradientPicker(prev => !prev); setShowPicker(false);}} />
{showPicker && (
<div className={styles.pickerPopover}>
<SwatchColorPicker
columnCount={5}
cellShape="square"
cellHeight={25}
cellWidth={25}
colorCells={colorCells}
aria-labelledby="swatch-picker"
onChange={(event, id, color) => {console.log('Color changed:', id, color);if (color) {setClickColor(color);}}}/>
</div>
)
}
{showGradientPicker && (
<div className={styles.pickerPopover}>
<SwatchColorPicker
columnCount={4}
cellShape="circle"
cellHeight={30}
cellWidth={30}
colorCells={gradientColorCells}
onRenderColorCellContent={renderGradientCell}
aria-labelledby="gradient-picker"
onChange={(event, id, color) => {if (color) setGradientColor(color);}}/>
</div>
)
}
</div>
</header>
{/* Main content area with buttons */}
<div className={styles.buttonGrid}>
{['Home', 'New Request', 'All Details', 'Budget', 'Management', 'Branding'].map((label, idx) => (
<button key={idx} className={styles.squareButton} style={{ background: gradientColor ? gradientColor : (clickColor || defaultSolidColor),}}> {label}</button>
))}
</div>
{/* Footer section with save and reset buttons */}
<footer className={styles.footer} style={{ backgroundColor: clickColor || defaultSolidColor }}>
<div>
<button className={styles.footerBtn} onClick={handleSave} >Save Colors</button>
<button className={styles.footerBtn} onClick={handleReset}>Reset to Default</button>
</div>
<span>Footer Section</span>
</footer>
</section>
)};
This code will create the header and footer sections, and in between, it adds six buttons. Additionally, it includes the save colors and reset to default buttons in the footer section, along with their corresponding functionality.
- Add the styles below to the .scss file.
@import '~@fluentui/react/dist/sass/References.scss';
.webpartWrapper {
border: 1px solid #ccc;
padding: 16px;
text-align: center;
font-family: 'Segoe UI', sans-serif;
}
.header, .footer {
height: 60px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 16px;
font-weight: bold;
font-size: 20px;
border: 1px solid #ccc;
border-radius: 6px;
margin-bottom: 20px;
}
.contentArea {
display: flex;
flex-direction: column;
gap: 16px;
align-items: center;
}
.navButtons {
display: grid;
grid-template-columns: repeat(3, auto);
gap: 16px;
button {
background-color: black;
color: white;
border: none;
padding: 12px 24px;
border-radius: 8px;
font-weight: bold;
cursor: pointer;
&:hover {
background-color: #333;
}
}
}
.iconRow {
text-align: center;
.paletteIcon {
font-size: 24px;
cursor: pointer;
}
}
.pickerContainer {
margin-top: 10px;
}
.actions {
display: flex;
gap: 16px;
button {
background-color: #e7e7e7;
border: 1px solid #ccc;
padding: 10px 20px;
border-radius: 4px;
font-weight: bold;
&:hover {
background-color: #d5d5d5;
}
}
}
.paletteIcon {
font-size: 20px;
cursor: pointer;
margin-left: 10px;
color: #333;
&:hover {
color: #0078d4;
}
}
.buttonGrid {
display: grid;
grid-template-columns: repeat(3, 120px);
grid-gap: 16px;
justify-content: center;
margin-bottom: 20px;
}
.squareButton {
height: 60px;
width: 120px;
font-weight: bold;
border: 1px solid #000;
background: none;
border-radius: 8px;
cursor: pointer;
}
.pickerContainer {
margin-bottom: 20px;
}
.footer {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 16px;
}
.footerBtn {
padding: 4px 10px;
font-size: 14px;
margin-right: 10px;
}
.paletteWrapper {
position: relative;
display: inline-block;
}
.pickerPopover {
position: absolute;
top: 100%;
right: 0;
background: #fff;
border: 1px solid #ccc;
padding: 6px;
border-radius: 4px;
z-index: 999;
box-shadow: 0 2px 8px rgba(0,0,0,0.2);
}
- Here is the final .tsx file code.
import * as React from 'react';
import styles from './SwatchColorPickerWebpart.module.scss';
import type { ISwatchColorPickerWebpartProps } from './ISwatchColorPickerWebpartProps';
import { useState, useEffect } from 'react';
import { IColorCellProps, SwatchColorPicker } from '@fluentui/react/lib/SwatchColorPicker';
import { FontIcon } from '@fluentui/react/lib/Icon';
const SwatchColorPickerWebpart: React.FC<ISwatchColorPickerWebpartProps> = (props) => {
const [clickColor, setClickColor] = useState<string>('');
const [showPicker, setShowPicker] = useState<boolean>(false);
const [gradientColor, setGradientColor] = useState<string>('');
const [showGradientPicker, setShowGradientPicker] = useState<boolean>(false);
const [defaultSolidColor, setDefaultSolidColor] = useState<string>('');
const [defaultGradientColor, setDefaultGradientColor] = useState<string>('');
const colorCells = [
{ id: 'darkRed', color: '#a4262c' },
{ id: 'burgundy', color: '#d13438' },
{ id: 'rust', color: '#ca5010' },
{ id: 'goldenrod', color: '#986f0b' },
{ id: 'forestGreen', color: '#498205' },
{ id: 'teal', color: '#007d84' },
{ id: 'darkTeal', color: '#006666' },
{ id: 'blue', color: '#0078d4' },
{ id: 'cornflower', color: '#4f6bed' },
{ id: 'navy', color: '#004e8c' },
{ id: 'indigo', color: '#373277' },
{ id: 'purple', color: '#8764b8' },
{ id: 'magenta', color: '#c239b3' },
{ id: 'gray', color: '#7a7574' },
{ id: 'lightPink1', color: '#f4abba' },
{ id: 'lightPink2', color: '#f79999' },
{ id: 'lightPink3', color: '#f3d6d2' },
{ id: 'peach', color: '#fce100' },
{ id: 'mintGreen', color: '#c7e0c4' },
{ id: 'lightCyan', color: '#b2e0e6' },
{ id: 'aqua', color: '#b2dfdb' },
{ id: 'paleBlue1', color: '#dae8fc' },
{ id: 'paleBlue2', color: '#cfe2f3' },
{ id: 'skyBlue', color: '#9fc5e8' },
{ id: 'lavender', color: '#d9d2e9' },
{ id: 'paleLavender', color: '#cfe2f3' },
{ id: 'lightGray', color: '#e6e6e6' },
];
const gradientColorCells = [
{ id: 'a', label: 'redBlueGradient', color: 'linear-gradient(0, red, blue)' },
{ id: 'b', label: 'greenGradient', color: 'linear-gradient(0, grey, green)' },
{ id: 'c', label: 'yellowGradient', color: 'linear-gradient(0, grey, yellow)' },
{ id: 'd', label: 'magentaGradient', color: 'linear-gradient(0, grey, magenta)' },
{ id: 'e', label: 'cyanGradient', color: 'linear-gradient(0, #038387, #ca5010)' },
{ id: 'f', label: 'ygGradient', color: 'linear-gradient(0, #8cbd18, #69797e)' },
{ id: 'g', label: 'grayGreen', color: 'linear-gradient(0, #0b6a0b, #69797e)' },
{ id: 'h', label: 'gray', color: '#7a7574' },
];
const renderGradientCell = (cellProps: IColorCellProps): JSX.Element => {
return (
<div style={{width: '100%', height: '100%', borderRadius: '50%', background: cellProps.color, }}/>
);
};
useEffect(() => {
const fetchColors = async () => {
try {
const item = await props.sp.web.lists.getByTitle("ColorSettings").items.select("Title", "SolidColor", "GradientColor", "DefaultSolidColor", "DefaultGradientColor")
.filter(`Title eq 'ITEM1'`)
.top(1)();
if (item.length > 0) {
const data = item[0];
setClickColor(data.SolidColor || data.DefaultSolidColor);
setGradientColor(data.GradientColor || data.DefaultGradientColor);
setDefaultSolidColor(data.DefaultSolidColor);
setDefaultGradientColor(data.DefaultGradientColor);
}
} catch (err) {
console.error("Error fetching list data:", err);
}
};
fetchColors();
}, []);
const handleSave = async () => {
try {
await props.sp.web.lists.getByTitle("ColorSettings").items.getById(1).update({SolidColor: clickColor,GradientColor: gradientColor});
alert("Colors saved successfully!");
} catch (err) {
console.error("Error saving colors:", err);
}
};
const handleReset = async () => {
try {
await props.sp.web.lists.getByTitle("ColorSettings").items.getById(1).update({SolidColor: null,GradientColor: null});
setClickColor(defaultSolidColor);
setGradientColor(defaultGradientColor);
alert("Colors reset to default!");
} catch (err) {
console.error("Error resetting colors:", err);
}
};
return (
<section className={`${styles.webpartWrapper}`}>
{/* Header section with color pickers */}
<header className={styles.header} style={{ backgroundColor: clickColor || defaultSolidColor }}>
<span>Header Section</span>
<div className={styles.paletteWrapper}>
<FontIcon iconName="Color" className={styles.paletteIcon} title="Choose Solid Color" onClick={() => {setShowPicker(prev => !prev);setShowGradientPicker(false);}}/>
<FontIcon iconName="BackgroundColor" className={styles.paletteIcon} title="Choose Gradient Color" onClick={() => {setShowGradientPicker(prev => !prev); setShowPicker(false);}} />
{showPicker && (
<div className={styles.pickerPopover}>
<SwatchColorPicker
columnCount={5}
cellShape="square"
cellHeight={25}
cellWidth={25}
colorCells={colorCells}
aria-labelledby="swatch-picker"
onChange={(event, id, color) => {console.log('Color changed:', id, color);if (color) {setClickColor(color);}}}/>
</div>
)
}
{showGradientPicker && (
<div className={styles.pickerPopover}>
<SwatchColorPicker
columnCount={4}
cellShape="circle"
cellHeight={30}
cellWidth={30}
colorCells={gradientColorCells}
onRenderColorCellContent={renderGradientCell}
aria-labelledby="gradient-picker"
onChange={(event, id, color) => {if (color) setGradientColor(color);}}/>
</div>
)
}
</div>
</header>
{/* Main content area with buttons */}
<div className={styles.buttonGrid}>
{['Home', 'New Request', 'All Details', 'Budget', 'Management', 'Branding'].map((label, idx) => (
<button key={idx} className={styles.squareButton} style={{ background: gradientColor ? gradientColor : (clickColor || defaultSolidColor),}}> {label}</button>
))}
</div>
{/* Footer section with save and reset buttons */}
<footer className={styles.footer} style={{ backgroundColor: clickColor || defaultSolidColor }}>
<div>
<button className={styles.footerBtn} onClick={handleSave} >Save Colors</button>
<button className={styles.footerBtn} onClick={handleReset}>Reset to Default</button>
</div>
<span>Footer Section</span>
</footer>
</section>
)};
export default SwatchColorPickerWebpart;
This way, we can utilize the Fluent UI swatch color picker control in the SharePoint Framework web part in real-world scenarios.
Deploy SPFx Fluent UI Swatch Color Picker Webpart
To deploy the SPFx client-side web part to your SharePoint Online app catalog site or site collection app catalog, run the commands below, which will create the .sppkg file under the SharePoint folder.
gulp bundle --ship
gulp package-solution --ship
This way, we can use the Fluent UI swatch color picker control in the SharePoint framework web part.
I hope you found this article helpful! In this article, I explain how to use the Fluent UI Swatch color picker React component in the SharePoint framework web part, providing two examples: changing the button’s background color when the user clicks the color cell, and changing the button’s background when the user hovers over the color.
You may also like the following SPFx tutorials:
- SPFx Fluent UI Basic List Example
- SPFx SwatchColorPicker Office UI Fabric React Control example
- SPFx – Bind dropdown list from SharePoint list using PnP
- Configure SharePoint Framework Properties and PreconfiguredEntries
- How to get user details using Microsoft Graph API in SPFx
- Send Email in SPFx using Microsoft Graph API and PnP JS

Hey! I’m Bijay Kumar, founder of SPGuides.com and a Microsoft Business Applications MVP (Power Automate, Power Apps). I launched this site in 2020 because I truly enjoy working with SharePoint, Power Platform, and SharePoint Framework (SPFx), and wanted to share that passion through step-by-step tutorials, guides, and training videos. My mission is to help you learn these technologies so you can utilize SharePoint, enhance productivity, and potentially build business solutions along the way.