Skip to content

Commit 3402b05

Browse files
authored
Merge pull request #651 from ValerasNarbutas/feature/brandCenterCustomFontSupport
Feature/brand center custom font support
2 parents 30ddd26 + f0f87dd commit 3402b05

16 files changed

+1108
-0
lines changed
19.3 KB
Loading
14.1 KB
Loading
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
# PropertyFieldBrandFontPicker control
2+
3+
This control generates a font picker that reads from SharePoint Brand Center and allows users to select corporate-approved fonts for their web parts. It supports both Brand Center fonts, system fonts, and custom font tokens with preview capabilities.
4+
5+
**PropertyFieldBrandFontPicker**
6+
7+
![PropertyFieldBrandFontPicker](../assets/PropertyFieldBrandFontPicker.png)
8+
9+
**PropertyFieldBrandFontPicker with font preview**
10+
11+
![Brand Font Picker with preview](../assets/brandfontpicker-preview.png)
12+
13+
## How to use this control in your solutions
14+
15+
1. Check that you installed the `@pnp/spfx-property-controls` dependency. Check out The [getting started](../../#getting-started) page for more information about installing the dependency.
16+
2. Import the following modules to your component:
17+
18+
```TypeScript
19+
import { PropertyFieldBrandFontPicker } from '@pnp/spfx-property-controls/lib/PropertyFieldBrandFontPicker';
20+
```
21+
22+
3. Create a new property for your web part, for example:
23+
24+
```TypeScript
25+
export interface IPropertyControlsTestWebPartProps {
26+
brandFont: string;
27+
}
28+
```
29+
30+
4. Add the custom property control to the `groupFields` of the web part property pane configuration:
31+
32+
```TypeScript
33+
PropertyFieldBrandFontPicker('brandFont', {
34+
label: 'Brand Font',
35+
initialValue: this.properties.brandFont,
36+
onSelectionChanged: (fontToken) => {
37+
this.properties.brandFont = fontToken.value;
38+
this.onPropertyPaneFieldChanged('brandFont', fontToken.value);
39+
},
40+
context: this.context,
41+
showPreview: true,
42+
key: 'brandFontFieldId'
43+
})
44+
```
45+
46+
## Using Custom Font Tokens
47+
48+
You can provide your own list of font tokens instead of relying on Brand Center:
49+
50+
```TypeScript
51+
import { IBrandFontToken } from '@pnp/spfx-property-controls/lib/PropertyFieldBrandFontPicker';
52+
53+
const customFontTokens: IBrandFontToken[] = [
54+
{
55+
name: 'corporateHeading',
56+
displayName: 'Corporate Heading Font',
57+
value: '"Montserrat", sans-serif',
58+
category: 'custom'
59+
},
60+
{
61+
name: 'corporateBody',
62+
displayName: 'Corporate Body Font',
63+
value: '"Open Sans", sans-serif',
64+
category: 'custom'
65+
}
66+
];
67+
68+
PropertyFieldBrandFontPicker('brandFont', {
69+
label: 'Custom Brand Font',
70+
initialValue: this.properties.brandFont,
71+
onSelectionChanged: (fontToken) => {
72+
this.properties.brandFont = fontToken.value;
73+
this.onPropertyPaneFieldChanged('brandFont', fontToken.value);
74+
},
75+
context: this.context,
76+
customFontTokens: customFontTokens,
77+
showPreview: true,
78+
key: 'brandFontFieldId'
79+
})
80+
```
81+
82+
## Implementation
83+
84+
The `PropertyFieldBrandFontPicker` control can be configured with the following properties:
85+
86+
| Property | Type | Required | Description |
87+
| ---- | ---- | ---- | ---- |
88+
| label | string | no | Property field label displayed on top. |
89+
| initialValue | string | no | Initial font value to be selected. |
90+
| onSelectionChanged | function | yes | Callback function when a font is selected. Returns the selected IBrandFontToken. |
91+
| context | BaseComponentContext | yes | The SPFx component context. |
92+
| customFontTokens | IBrandFontToken[] | no | Array of custom font tokens to display instead of Brand Center fonts. |
93+
| showPreview | boolean | no | Whether to display font preview text in the dropdown. Default is true. |
94+
| disabled | boolean | no | Whether the control is disabled. Default is false. |
95+
| onFontTokensLoaded | function | no | Callback function called when font tokens are loaded. |
96+
| loadingErrorMessage | string | no | Custom error message to display when font loading fails. |
97+
| key | string | yes | An UNIQUE key indicates the identity of this control. |
98+
99+
Interface `IBrandFontToken`:
100+
101+
| Property | Type | Required | Description |
102+
| ---- | ---- | ---- | ---- |
103+
| name | string | yes | Unique identifier for the font token. |
104+
| displayName | string | yes | Display name shown in the dropdown. |
105+
| value | string | yes | CSS font-family value (e.g., '"Lato", sans-serif'). |
106+
| preview | string | no | Optional preview text. |
107+
| category | string | no | Category for grouping (e.g., 'site', 'microsoft', 'custom'). |
108+
| fileUrl | string | no | Optional URL to font file or CSS. |
109+
110+
## Example
111+
112+
```TypeScript
113+
import * as React from 'react';
114+
import * as ReactDom from 'react-dom';
115+
import { Version } from '@microsoft/sp-core-library';
116+
import {
117+
BaseClientSideWebPart,
118+
IPropertyPaneConfiguration,
119+
PropertyPaneTextField
120+
} from '@microsoft/sp-webpart-base';
121+
122+
import { PropertyFieldBrandFontPicker } from '@pnp/spfx-property-controls/lib/PropertyFieldBrandFontPicker';
123+
124+
export interface IPropertyControlsTestWebPartProps {
125+
brandFont: string;
126+
}
127+
128+
export default class PropertyControlsTestWebPart extends BaseClientSideWebPart<IPropertyControlsTestWebPartProps> {
129+
130+
public render(): void {
131+
const element: React.ReactElement<IPropertyControlsTestWebPartProps> = React.createElement(
132+
PropertyControlsTest,
133+
{
134+
brandFont: this.properties.brandFont
135+
}
136+
);
137+
138+
ReactDom.render(element, this.domElement);
139+
}
140+
141+
protected get propertyPaneConfiguration(): IPropertyPaneConfiguration {
142+
return {
143+
pages: [
144+
{
145+
header: {
146+
description: strings.PropertyPaneDescription
147+
},
148+
groups: [
149+
{
150+
groupName: strings.BasicGroupName,
151+
groupFields: [
152+
PropertyFieldBrandFontPicker('brandFont', {
153+
label: 'Brand Font',
154+
initialValue: this.properties.brandFont,
155+
onSelectionChanged: (fontToken) => {
156+
this.properties.brandFont = fontToken.value;
157+
this.onPropertyPaneFieldChanged('brandFont', fontToken.value);
158+
},
159+
context: this.context,
160+
showPreview: true,
161+
key: 'brandFontFieldId'
162+
})
163+
]
164+
}
165+
]
166+
}
167+
]
168+
};
169+
}
170+
}
171+
```
172+
173+
![](https://telemetry.sharepointpnp.com/sp-dev-fx-property-controls/wiki/PropertyFieldBrandFontPicker)

docs/documentation/docs/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ telemetry.optOut();
6060
The following controls are currently available:
6161

6262
- [PropertyFieldButton](./controls/PropertyFieldButton) (Property pane Button)
63+
- [PropertyFieldBrandFontPicker](./controls/PropertyFieldBrandFontPicker) (Property pane Brand Center font selector)
6364
- [PropertyFieldCodeEditor](./controls/PropertyFieldCodeEditor) (Property pane code editor)
6465
- [PropertyFieldCollectionData](./controls/PropertyFieldCollectionData) (Property pane collection data editor)
6566
- [PropertyFieldColorPicker](./controls/PropertyFieldColorPicker) (Property pane color picker)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './propertyFields/brandFontPicker';

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export * from './PropertyFieldEnterpriseTermPicker';
88
export * from './PropertyFieldMultiSelect';
99
export * from './PropertyFieldNumber';
1010
export * from './PropertyFieldGuid';
11+
export * from './PropertyFieldBrandFontPicker';
1112

1213
export * from './PropertyFieldButtonWithCallout';
1314
export * from './PropertyFieldCheckboxWithCallout';
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
import { IPropertyPaneCustomFieldProps } from '@microsoft/sp-property-pane';
2+
import { BaseComponentContext } from '@microsoft/sp-component-base';
3+
4+
/**
5+
* Brand font token interface
6+
*/
7+
export interface IBrandFontToken {
8+
/**
9+
* The CSS variable name (e.g., "fontFamilyBase")
10+
*/
11+
name: string;
12+
13+
/**
14+
* The display name for the font
15+
*/
16+
displayName: string;
17+
18+
/**
19+
* The font family value (e.g., "Segoe UI, system-ui, sans-serif")
20+
*/
21+
value: string;
22+
23+
/**
24+
* Optional preview text
25+
*/
26+
preview?: string;
27+
28+
/**
29+
* Optional font file URL
30+
*/
31+
fileUrl?: string;
32+
33+
/**
34+
* Font source category
35+
*/
36+
category?: 'site' | 'organization' | 'microsoft';
37+
}
38+
39+
/**
40+
* Public properties of the PropertyFieldBrandFontPicker custom field
41+
*/
42+
export interface IPropertyFieldBrandFontPickerProps {
43+
/**
44+
* Property field label displayed on top
45+
*/
46+
label: string;
47+
48+
/**
49+
* Defines an onPropertyChange function to raise when the selected value changes.
50+
* Normally this function must be defined with the 'this.onPropertyChange'
51+
* method of the web part object.
52+
*/
53+
onPropertyChange(propertyPath: string, oldValue: any, newValue: any): void; // eslint-disable-line @typescript-eslint/no-explicit-any
54+
55+
/**
56+
* The initial selected font token name
57+
*/
58+
initialValue?: string;
59+
60+
/**
61+
* Whether the property pane field is enabled or not
62+
*/
63+
disabled?: boolean;
64+
65+
/**
66+
* The context object of the SPFx component
67+
*/
68+
context: BaseComponentContext;
69+
70+
/**
71+
* Custom properties object
72+
*/
73+
properties?: any; // eslint-disable-line @typescript-eslint/no-explicit-any
74+
75+
/**
76+
* An unique key that indicates the identity of this control
77+
*/
78+
key?: string;
79+
80+
/**
81+
* Whether the property pane field is visible or not
82+
*/
83+
isHidden?: boolean;
84+
85+
/**
86+
* Custom font tokens to use as fallback or override
87+
*/
88+
customFontTokens?: IBrandFontToken[];
89+
90+
/**
91+
* Callback function that will be called on font tokens loaded
92+
*/
93+
onFontTokensLoaded?: (tokens: IBrandFontToken[]) => void;
94+
95+
/**
96+
* Whether to show preview text in the dropdown
97+
*/
98+
showPreview?: boolean;
99+
100+
/**
101+
* Custom preview text to use
102+
*/
103+
previewText?: string;
104+
105+
/**
106+
* Error message to display when font tokens cannot be loaded
107+
*/
108+
loadingErrorMessage?: string;
109+
110+
/**
111+
* Whether to use system fonts as fallback when Brand Center is not available
112+
*/
113+
useSystemFallback?: boolean;
114+
}
115+
116+
/**
117+
* Private properties of the PropertyFieldBrandFontPicker custom field.
118+
* We separate public & private properties to include onRender & onDispose method waited
119+
* by the PropertyPane control without asking it from the developer
120+
*/
121+
export interface IPropertyFieldBrandFontPickerPropsInternal extends IPropertyPaneCustomFieldProps {
122+
label: string;
123+
initialValue?: string;
124+
targetProperty: string;
125+
context: BaseComponentContext;
126+
onPropertyChange(propertyPath: string, oldValue: any, newValue: any): void; // eslint-disable-line @typescript-eslint/no-explicit-any
127+
properties: any; // eslint-disable-line @typescript-eslint/no-explicit-any
128+
disabled?: boolean;
129+
key: string;
130+
isHidden?: boolean;
131+
customFontTokens?: IBrandFontToken[];
132+
onFontTokensLoaded?: (tokens: IBrandFontToken[]) => void;
133+
showPreview?: boolean;
134+
previewText?: string;
135+
loadingErrorMessage?: string;
136+
useSystemFallback?: boolean;
137+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { IBrandFontToken } from './IPropertyFieldBrandFontPicker';
2+
import { BaseComponentContext } from '@microsoft/sp-component-base';
3+
4+
/**
5+
* PropertyFieldBrandFontPickerHost properties interface
6+
*/
7+
export interface IPropertyFieldBrandFontPickerHostProps {
8+
label: string;
9+
initialValue?: string;
10+
targetProperty: string;
11+
context: BaseComponentContext;
12+
onSelectionChanged?: (option: IBrandFontToken) => void;
13+
disabled?: boolean;
14+
customFontTokens?: IBrandFontToken[];
15+
onFontTokensLoaded?: (tokens: IBrandFontToken[]) => void;
16+
showPreview?: boolean;
17+
previewText?: string;
18+
loadingErrorMessage?: string;
19+
useSystemFallback?: boolean;
20+
}
21+
22+
/**
23+
* PropertyFieldBrandFontPickerHost state interface
24+
*/
25+
export interface IPropertyFieldBrandFontPickerHostState {
26+
loading: boolean;
27+
fontTokens: IBrandFontToken[];
28+
selectedToken?: IBrandFontToken;
29+
errorMessage?: string;
30+
}

0 commit comments

Comments
 (0)