-
Notifications
You must be signed in to change notification settings - Fork 1k
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
🙏 SPFx v1.13 beta20 web part template feedback - please don't bloat the default class #PleaseChange #7308
Comments
Thank you for reporting this issue. We will be triaging your incoming issue as soon as possible. |
For those who haven't installed the beta, this is what you get with a new default class using beta 20 when creating a new web part and accept all defaults (ie: don't pick React) import { Version } from '@microsoft/sp-core-library';
import {
IPropertyPaneConfiguration,
PropertyPaneTextField
} from '@microsoft/sp-property-pane';
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
import {
ThemeProvider,
ThemeChangedEventArgs,
IReadonlyTheme,
ITheme
} from '@microsoft/sp-component-base';
import { escape } from '@microsoft/sp-lodash-subset';
import styles from './HelloWorldWebPart.module.scss';
import * as strings from 'HelloWorldWebPartStrings';
export interface IHelloWorldWebPartProps {
description: string;
}
export default class HelloWorldWebPart extends BaseClientSideWebPart<IHelloWorldWebPartProps> {
private _themeProvider: ThemeProvider;
private _themeVariant: IReadonlyTheme | undefined;
private _isDarkTheme: boolean = false;
private _environmentMessage: string = '';
private _hasTeamsContext: boolean = false;
protected onInit(): Promise<void> {
this._hasTeamsContext = !!this.context.sdks.microsoftTeams;
if (this._hasTeamsContext) {
// handling MS Teams theme
const teamsTheme = this.context.sdks.microsoftTeams.context.theme;
this._updateTheme(teamsTheme);
this.context.sdks.microsoftTeams.teamsJs.registerOnThemeChangeHandler(this._handleTeamsThemeChangedEvent);
}
else {
// Consume the new ThemeProvider service
this._themeProvider = this.context.serviceScope.consume(ThemeProvider.serviceKey);
// If it exists, get the theme variant
this._themeVariant = this._themeProvider.tryGetTheme();
this._updateTheme(this._themeVariant);
// Register a handler to be notified if the theme variant changes
this._themeProvider.themeChangedEvent.add(this, this._handleSPThemeChangedEvent);
}
this._environmentMessage = this._getEnvironmentMessage();
return super.onInit();
}
public render(): void {
this.domElement.innerHTML = `
<div class="${ styles.helloWorld } ${ this._hasTeamsContext ? styles.teams : '' }">
<div class="${ styles.container }">
<div class="${ styles.row }">
<div class="${ styles.column } ${ styles.center }">
<img src="${this._isDarkTheme ? require('./assets/welcome-dark.png') : require('./assets/welcome-light.png')}" class="${styles.welcomeImage}" />
</div>
</div>
<div class="${ styles.row }">
<div class="${ styles.column } ${ styles.center }">
<span class="${ styles.title }">Well done, ${this.context.pageContext.user.displayName}!</span>
<p class="${ styles.subTitle }">${this._environmentMessage}</p>
<p class="${ styles.subTitle }">Web part property value: <span class="${ styles.description }"> ${escape(this.properties.description)}</span></p>
</div>
</div>
<div class="${ styles.row }">
<div class="${ styles.column }">
<span class="${ styles.header }">Welcome to SharePoint Framework!</span>
<p class="${ styles.content }">
The SharePoint Framework (SPFx) is a extensibility model for Microsoft Viva, Microsoft Teams and SharePoint. It's the easiest way to extend Microsoft 365 with automatic Single Sign On, automatic hosting and industry standard tooling.
</p>
<span class="${ styles.subheader }">Learn more about SPFx development:</span>
<p class="${ styles.content }">
<ul>
<li><a class="${styles.link}" href="https://aka.ms/spfx" target="_blank">Overview of the SharePoint Framework</a></li>
<li><a class="${styles.link}" href="https://docs.microsoft.com/en-us/sharepoint/dev/spfx/web-parts/basics/notes-on-solution-packaging" target="_blank">SharePoint solution packaging</a></li>
<li><a class="${styles.link}" href="https://docs.microsoft.com/en-us/sharepoint/dev/spfx/build-for-teams-overview" target="_blank">Build for Microsoft Teams using SharePoint Framework</a></li>
<li><a class="${styles.link}" href="https://docs.microsoft.com/en-us/sharepoint/dev/spfx/web-parts/get-started/use-fabric-react-components" target="_blank">Use Fluent UI components in your SharePoint client-side web part</a></li>
<li><a class="${styles.link}" href="https://docs.microsoft.com/en-us/sharepoint/dev/spfx/web-parts/get-started/using-microsoft-graph-apis" target="_blank">Use Microsoft Graph in your solution</a></li>
<li><a class="${styles.link}" href="https://docs.microsoft.com/en-us/javascript/api/overview/sharepoint?view=sp-typescript-latest" target="_blank">SharePoint Framework API reference</a></li>
<li><a class="${styles.link}" href="https://aka.ms/m365pnp" target="_blank">Microsoft 365 Community Assets - Calls, samples and documentation</a></li>
<li><a class="${styles.link}" href="https://aka.ms/m365/devprogram" target="_blank">Register to Microsoft 365 Developer program for a free developer tenant</a></li>
</ul>
</p>
</div>
</div>
</div>
</div>`;
}
/**
* Update the current theme variant reference and re-render.
*
* @param args The new theme
*/
private _handleSPThemeChangedEvent = (args: ThemeChangedEventArgs): void => {
this._themeVariant = args.theme;
this._updateTheme(this._themeVariant);
this.render();
}
/**
* Handle Teams theme change callback.
*
* @param args The new theme
*/
private _handleTeamsThemeChangedEvent = (theme: string): void => {
this._updateTheme(theme);
this.render();
}
/**
* Updates fields based on the new theme
* @param currentTheme updated theme
*/
private _updateTheme = (currentTheme: IReadonlyTheme | string) => {
this._setIsDarkTheme(currentTheme);
this._setCSSVariables();
}
/**
* Updates the _isDarkTheme based on current SharePoint or Teams theme
*/
private _setIsDarkTheme = (currentTheme: IReadonlyTheme | string) => {
if (typeof currentTheme === 'string') { // Teams theme
this._isDarkTheme = currentTheme !== 'default'; // contrast theme is interpreted as dark
}
else { // SharePoint theme
const theme = currentTheme as ITheme;
this._isDarkTheme = !!theme && !!theme.isInverted;
}
}
private _setCSSVariables = () => {
let primaryText = '#323130'; // default
let linkText = '#03787c';
if (this._themeVariant) {
const {
semanticColors
} = this._themeVariant;
primaryText = semanticColors.bodyText;
linkText = semanticColors.link;
}
else if (this._hasTeamsContext) { // fallback for Teams
primaryText = this._isDarkTheme ? '#FFFFFF' : '#242424';
linkText = this._isDarkTheme ? '#FFFFFF' : '#494B83';
}
else { // fallback for single app page
primaryText = this._isDarkTheme ? '#3a96dd' : '#323130';
linkText = this._isDarkTheme ? '#3a96dd' : '#03787c';
}
this.domElement.style.setProperty('--primaryText', primaryText);
this.domElement.style.setProperty('--linkText', linkText);
}
private _getEnvironmentMessage = (): string => {
// checking for local environment
let isLocal: boolean = false;
const {
loaderConfig
} = this.manifest;
if (loaderConfig && loaderConfig.internalModuleBaseUrls && loaderConfig.internalModuleBaseUrls.length) {
isLocal = /^http(s)?\:\/\/localhost/gmi.test(loaderConfig.internalModuleBaseUrls[0]);
}
if (this._hasTeamsContext) { // running in Teams
return isLocal ? strings.AppLocalEnvironmentTeams : strings.AppTeamsTabEnvironment;
}
return isLocal ? strings.AppLocalEnvironmentSharePoint : strings.AppSharePointEnvironment;
}
protected onDispose(): void {
//
// unregistering theme changed handlers
//
if (this._hasTeamsContext) {
this.context.sdks.microsoftTeams.teamsJs.registerOnThemeChangeHandler(null);
}
else {
this._themeProvider.themeChangedEvent.remove(this, this._handleSPThemeChangedEvent);
}
}
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
})
]
}
]
}
]
};
}
} |
I just noticed the change as well. While I welcome proper guidance on how to properly support Microsoft Teams Themes including things like handling a theme change, this certainly is intimidating for a new user just getting started. |
I agree that I think it's excellent to provide guidance, I'm not in favor of this code being included in the base web part in this manner by default. I do not do theming support in this manner and don't want the added overhead of having to remove all this code every time, I start a new project. |
I'm going to figure out how to move this to the discussion feature in github. |
Few comments and let's move this to the discussion side for clarity as it's more discussion, rather than an issue. This is in the beta release and it's intended for having these kind of discussions.
Why did we do this?
I'm moving this to discussions side to keep the issue list more specifically for issues. Similar clean up is happening for older issues. |
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
Target SharePoint environment
SharePoint Online
What SharePoint development model, framework, SDK or API is this about?
💥 SharePoint Framework
Developer environment
macOS
What browser(s) / client(s) have you tested
Additional environment details
Describe the bug / error
TLDR
The new web part template introduced within the most recent beta (#20) for the upcoming 1.13.0 SPFx release is loaded with additional code that's not necessary. Please move this to a new
ThemedBaseClientSideWebPart
class & inherit from it.More
The new base web part class is now loaded with theming bloat in the simplest "hello world" web part using no web framework. Specifically:
onInit()
method to support MS Teams themesIMHO, this is bad for multiple reasons:
Steps to reproduce
npm install @microsoft/generator-sharepoint@next -g
Expected behavior
Default projects should not be filled with boilerplate code that's not intended to be modified. That code should be in base classes.
Proposed solution
Why not push ALL this stuff in the three bullet points above into a new class and inherit from it? For instance:
create a new base class and include it within the @microsoft/sp-webpart-base:
100% of the three bullet items from above into this new class (including the private members &
onInit()
), along with theimport
dependencies & remove all that from the new web part class templatechange the web part class template to create a web part that looks like this:
bask in your coding glory
The text was updated successfully, but these errors were encountered: