SPFX
SPFX react Hooks
On 18/12/2024
Base hooks context
import { WebPartContext } from "@microsoft/sp-webpart-base";
export interface iMAContext {
context: WebPartContext;
}
component
import * as React from 'react'; import styles from './MaCountries.module.scss'; import type { IMaCountriesProps } from './IMaCountriesProps'; import { iMAContext } from '../../../entities/iMAContext'; //import { escape } from '@microsoft/sp-lodash-subset'; export const MaCountriesContext = React.createContext
<({} as iMAContext); export const MaCountries: React.FunctionComponent = (props: IMaCountriesProps) => { return ( MaCountriesContext
.Provider value={{ context: props.context }}><div></
dfvdfv</div>MaCountriesContext
.Provider >
); };
webpart
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 'MaCountriesWebPartStrings';
import { MaCountries } from './components/MaCountries';
import { IMaCountriesProps } from './components/IMaCountriesProps';
export interface IMaCountriesWebPartProps {
description: string;
}
export default class MaCountriesWebPart extends BaseClientSideWebPart {
private _isDarkTheme: boolean;
public render(): void {
const element: React.ReactElement = React.createElement(
MaCountries,
{
description: this.properties.description,
context: this.context,
isDarkTheme: this._isDarkTheme
}
);
ReactDom.render(element, this.domElement);
}
protected onInit(): Promise {
return this._getEnvironmentMessage().then(message => {
});
}
private _getEnvironmentMessage(): Promise {
if (!!this.context.sdks.microsoftTeams) { // running in Teams, office.com or Outlook
return this.context.sdks.microsoftTeams.teamsJs.app.getContext()
.then(context => {
let environmentMessage: string = '';
switch (context.app.host.name) {
case 'Office': // running in Office
environmentMessage = this.context.isServedFromLocalhost ? strings.AppLocalEnvironmentOffice : strings.AppOfficeEnvironment;
break;
case 'Outlook': // running in Outlook
environmentMessage = this.context.isServedFromLocalhost ? strings.AppLocalEnvironmentOutlook : strings.AppOutlookEnvironment;
break;
case 'Teams': // running in 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: [
PropertyPaneTextField('description', {
label: strings.DescriptionFieldLabel
})
]
}
]
}
]
};
}
}
hide native CSS
@import '~@fluentui/react/dist/sass/References.scss';
div[data-automation-id="pageHeader"] {
display: none;
}
Shared css
@import '~@fluentui/react/dist/sass/References.scss';
/* remove this color TODO*/
html,
body {
background-color: #d2d9dd !important;
}
:global root-148.root-148.root-148.root-148.root-148 {
background-color: #d2d9dd !important;
}
:global CanvasSection {
background-color: #d2d9dd !important;
}
//global, hide not decored css or native hoverride
:global .fui-DatePicker__popupSurface {
background-color: #fff;
}
/* end remove this color TODO*/
$eulightBlue: #007dba;
$eulightDark: #10377A;
$euAlert: #AB0000;
$euGrey: #ECF6FA;
$euligthGrey: #D8E4EA;
$euTextColor: #4C7A8F;
$euAlertOrange: #E38100;
$euOkGreen: #00B400;
$red: #FA505C;
//bold
$fontBoldWeight: 600;
$fontBoldSize: 14px;
//bolder
$fontBolderWeight: 600;
$fontBolderSize: 16px;
//normal
$fontNormalWeight: 500;
$fontNormalSize: 12px;
//small
$fontSmallWeight: 500;
$fontSmallSize: 10px;
.shared {
.eutclear {
display: block;
clear: both;
line-height: 0;
}
.eutclearfix:before,
.eutclearfix:after {
display: table;
clear: both;
content: '';
}
.container {
// border: 1px solid black;
width: 100%;
// margin-right: auto;
// margin-left: auto;
}
@media (min-width: 576px) {
.container {
max-width: 540px;
}
}
@media (min-width: 768px) {
.container {
max-width: 720px;
}
}
@media (min-width: 992px) {
.container {
max-width: 960px;
}
}
@media (min-width: 1200px) {
.container {
max-width: 1140px;
}
}
.containerFluid {
width: 100%;
padding-right: 15px;
padding-left: 15px;
margin-right: auto;
margin-left: auto;
}
.row {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
}
.col3 {
margin: auto;
-webkit-box-flex: 0;
max-width: 100%;
flex: none;
-ms-flex: none;
}
@media (min-width: 576px) {
.col3 {
max-width: 100%;
flex: none;
-ms-flex: none;
}
}
@media (min-width: 768px) {
.col3 {
-webkit-box-flex: 0;
-ms-flex: 0 0 32%;
flex: 0 0 32%;
max-width: 32%;
}
}
@media (min-width: 992px) {
.col3 {
-webkit-box-flex: 0;
-ms-flex: 0 0 31%;
flex: 0 0 31%;
max-width: 31%;
}
}
@media (min-width: 1200px) {
.col3 {
-webkit-box-flex: 0;
-ms-flex: 0 0 32%;
flex: 0 0 32%;
max-width: 32%;
}
}
}
Gulp Bundle Issue Cannot Read Property Id Of Undefined
On 08/06/2021
Gulp bundle issue : Cannot read property 'id' of undefined
Gulp bundle issue : Field 'browser' doesn't contain a valid alias configuration
Gulp bundle issue : sub task errored after
Check that in your tsconfig.json, you've got this below :
"include": [
"src/**/*.ts", "src/**/*.tsx"
],
and not :
"include": [
"src/**/*.tsx"
],
SPLoaderError.loadComponentError
On 09/12/2020
SPFX react sur Internet explorer : [SPLoaderError.loadComponentError]: There was a network problem. This may be a problem with a HTTPS certificate. Make sure you have the right certificate.
It's not always à certificate error, in my case, i use code below in a service,
import 'core-js/modules/es6.string.includes.js';//in my case this line should be commented to fix the isssue
import 'core-js/modules/es6.number.is-nan.js';
import 'core-js/es6/array';
import 'es6-map/implement';
when including "@types/es6-promise": "^3.3.0" i don't need anymore import 'core-js/modules/es6.string.includes.js
Sharepoint Online Missing Icons
On 09/12/2020
Sharepoint missing icon on SPFX developpements
Some ican can be missing per exemple on :
SPFX missing icon as <i data-icon-name="Tag" class="ms-Button-icon icon-167" role="presentation" aria-hidden="true"></i>
So you simply have to add this code below after yours imports
import { initializeIcons } from 'office-ui-fabric-react/lib/Icons';
initializeIcons();
SPFX React Tips
On 02/09/2020
Override native css
:global(#spLeftNav) {
display: none;
}
:global(.CanvasZone) {
max-width: 100%;
}
Is member of
import 'core-js/modules/es6.string.includes.js';
import 'core-js/modules/es6.number.is-nan.js';
import 'core-js/es6/array';
import 'es6-map/implement';
import { sp,SPRest } from '@pnp/sp';
import { IWebPartContext } from '@microsoft/sp-webpart-base';
import * as React from 'react';
class PeopleService {
private _context: IWebPartContext;
private _localPnPSetup: SPRest;
public constructor(webPartContext: IWebPartContext) {
this._context = webPartContext;
// To limit the payload size, we set odata=nometadata
// We just need to get list items here
// We use a local configuration to avoid conflicts with other Web Parts
this._localPnPSetup = sp.configure({
headers: {
Accept: 'application/json; odata=nometadata',
},
}, this._context.pageContext.web.absoluteUrl);
}
public async isMemberOf(group: string): Promise{
let groups = await this._localPnPSetup.web.currentUser.groups.get();
let ret: boolean = false;
groups.map(grp =>{
if(grp.LoginName == group)
ret = true;
});
return ret;
}
public async isMemberOfanyGroup(groupNames: string[]): Promise{
let groups = await this._localPnPSetup.web.currentUser.groups.get();
let ret: boolean = false;
groups.map(grp =>{
groupNames.map(name =>{
console.log("name : '" + name + "' grp : '" + grp.LoginName + "'");
if(grp.LoginName == name)
ret = true;
});
});
return ret;
}
}
export default PeopleService;
Taxonomy, get tags, add tags
import { IWebPartContext } from '@microsoft/sp-webpart-base';
import { Session, ITermStore, ITermSet, ITermData, ITerm } from '@pnp/sp-taxonomy';
class TaxonomyService {
private _context: IWebPartContext;
public constructor(webPartContext: IWebPartContext) {
this._context = webPartContext;
}
public async getTags() : Promise{
console.log("Session");
const taxonomy = new Session(this._context.pageContext.site.absoluteUrl);
const store: any = taxonomy.termStores.getByName("Taxonomy_Wf8XzHaRobdAERjvvke+Tg==");
let datas = await store.getTermSetById("c18ff3e6-e4a8-4dcb-85f5-51171f4bbc11").terms.select('Name', 'Id', 'Parent').get();
let ret: string[] = [];
for(let i = 0 ; i < datas.length ; i++)
ret.push(datas[i]);
return datas;
}
public async addNewTag(tag){
const taxonomy = new Session(this._context.pageContext.site.absoluteUrl);
const store: any = taxonomy.termStores.getByName("Taxonomy_Wf8XzHaRobdAERjvvke+Tg==");
let datas = await store.getTermSetById("c18ff3e6-e4a8-4dcb-85f5-51171f4bbc11");
const term: ITerm & ITermData = await datas.addTerm(tag, 1036, true);
}
}
export default TaxonomyService;
SPFX pnp Taxonomy with internet explorer 11
On 26/06/2020
SPFX webpart query Taxonomy / Term store with @pnp/sp-taxonomy on ie / internet explorer
Your package.json must contains at least :
"@pnp/polyfill-ie11": "1.0.0",
"@pnp/sp": "1.2.7",
"@pnp/sp-clientsvc": "^1.3.9",
"@pnp/sp-taxonomy": "^1.3.9",
"@types/es6-promise": "0.0.33"
In your service where you want to query Term store, you should import :
import 'core-js/modules/es6.string.includes.js';
import 'core-js/modules/es6.number.is-nan.js';
import 'core-js/es6/array';
import 'es6-map/implement';
import { Session } from '@pnp/sp-taxonomy';