Handling theme changes on a MS Teams Tab WebPart


Using the latest SPFx version is possible to deploy a WebPart and Sync it with Microsoft Teams. In this article I am not going to show how to do it, but I leave some tips on how to prepare the WebPart to support theme colors on SharePoint and Teams Tab environments.

The Microsoft Teams environment has three different themes the user can choose from. The available themes are:
. Default (Light)
. Dark
. High Contrast

Since those themes are a user's choice, using the Site Collection's theme colors chosen by the administrator is not useful to a Teams Tab Environment. In fact, it may lead to an unpleasant experience to the end user. Let's say the user is using the MS Teams App with a dark theme but the site collection has a light theme applied. The result is a WebPart being rendered using a light pallete inside a dark environment.

So, if you're planning to migrate a SPFx WebPart to Microsoft Teams there are some steps that you should consider to handle the themes "issue".

To do that, 3 simple steps should be considered:

- Identify the Environment
- Get the applied theme on MS Teams App and handle the theme's changes
- Add separated styles to the SharePoint and MS Teams environments

In the main .ts file you only need to add some logics to the OnInit flow:


enum WebPartEnvironment {SharePoint = "sharepoint-environment", TeamsTab = "ms-teams-environment"};

export default class TeamsThemesWebPart extends BaseClientSideWebPart<ITeamsThemesWebPartProps> {

  public onInit<T>(): Promise<T> {

    if (this.context.microsoftTeams){

      this.domElement.classList.add(styles[WebPartEnvironment.TeamsTab]);

      return new Promise<T>((resolve)=>{

        // get theme from teams context
        this.context.microsoftTeams.getContext((context)=>{

            let teamsTheme = context.theme; // this can be 'default', 'dark' or 'contrast'
            this.domElement.classList.add(styles["ms-teams-theme-" + teamsTheme]);

            // regsiter the change theme event to switch theme classes
            this.context.microsoftTeams.registerOnThemeChangeHandler((theme)=> {
              this.domElement.classList.remove(styles["ms-teams-theme-default"], styles["ms-teams-theme-dark"], styles["ms-teams-theme-contrast"]);
              this.domElement.classList.add(styles["ms-teams-theme-" + theme]);
            });

            resolve();
        });
      });    

    }else{

      this.domElement.classList.add(styles[WebPartEnvironment.SharePoint]);
      return Promise.resolve();

    }
  }

  public render(): void {
    
    this.domElement.innerHTML = `
      <div class="${ styles.container }">
        <div class="${ styles.row }">
          <div class="${ styles.column }">
            <span class="${ styles.title }">Welcome to SharePoint!</span>
            <p class="${ styles.subTitle }">Customize SharePoint experiences using Web Parts.</p>
            <p class="${ styles.description }">${escape(this.properties.description)}</p>
            <a href="https://aka.ms/spfx" class="${ styles.button }">
              <span class="${ styles.label }">Learn more</span>
            </a>
          </div>
        </div>
      </div>`;

  }



On the SASS file, just separate the enviroments:


@import '~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss';

.ms-teams-environment{

  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  
  .container {
    max-width: 700px;
    margin: 0px auto;
    box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
  }

  .row {
    @include ms-Grid-row;
    @include ms-fontColor-white;
    padding: 20px;
  }

  .column {
    @include ms-Grid-col;
    @include ms-lg10;
    @include ms-xl8;
    @include ms-xlPush2;
    @include ms-lgPush1;
  }

  .title {
    @include ms-font-xl;
    @include ms-fontColor-white;
  }

  .subTitle {
    @include ms-font-l;
    @include ms-fontColor-white;
  }

  .description {
    @include ms-font-l;
    @include ms-fontColor-white;
  }

  .button {
    // Our button
    text-decoration: none;
    height: 32px;

    // Primary Button
    min-width: 80px;
    background-color: $ms-color-themePrimary;
    border-color: $ms-color-themePrimary;
    color: $ms-color-white;

    // Basic Button
    outline: transparent;
    position: relative;
    font-family: "Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;
    -webkit-font-smoothing: antialiased;
    font-size: $ms-font-size-m;
    font-weight: $ms-font-weight-regular;
    border-width: 0;
    text-align: center;
    cursor: pointer;
    display: inline-block;
    padding: 0 16px;

    .label {
      font-weight: $ms-font-weight-semibold;
      font-size: $ms-font-size-m;
      height: 32px;
      line-height: 32px;
      margin: 0 4px;
      vertical-align: top;
      display: inline-block;
    }
  }

  &.ms-teams-theme-default{

    .row {
      background-color: #eee;
    }

    .title {
      color:#333;
    }
  
    .subTitle {
      color:#333;
    }
  
    .description {
      color:#333;
    }

    .button{
      background-color: #ddd;
      border-color: #ccc;
      color: black;
    }
  }

  &.ms-teams-theme-dark{

    .row {
      background-color: #333;
    }

    .title {
      color:#ddd;
    }
  
    .subTitle {
      color:#ddd;
    }
  
    .description {
      color:#ddd;
    }

    .button{
      background-color: #444;
      border-color: #000;
      color: white;
    }

  }

  &.ms-teams-theme-contrast{
    .container{
      box-shadow: none;
    }
    .row {
      background-color: black;
      border: 1px solid white;
    }
    .title {
      color:white;
    }
  
    .subTitle {
      color:white;
    }
  
    .description {
      color:white;
    }

    .button{
      background-color: black;
      border: 1px solid;
      border-color: white;
      color: yellow;
    }
  }
  
}

.sharepoint-environment{
  .container {
    max-width: 700px;
    margin: 0px auto;
    box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
  }

  .row {
    @include ms-Grid-row;
    @include ms-fontColor-white;
    background-color: $ms-color-themeDark;
    padding: 20px;
  }

  .column {
    @include ms-Grid-col;
    @include ms-lg10;
    @include ms-xl8;
    @include ms-xlPush2;
    @include ms-lgPush1;
  }

  .title {
    @include ms-font-xl;
    @include ms-fontColor-white;
  }

  .subTitle {
    @include ms-font-l;
    @include ms-fontColor-white;
  }

  .description {
    @include ms-font-l;
    @include ms-fontColor-white;
  }

  .button {
    // Our button
    text-decoration: none;
    height: 32px;

    // Primary Button
    min-width: 80px;
    background-color: $ms-color-themePrimary;
    border-color: $ms-color-themePrimary;
    color: $ms-color-white;

    // Basic Button
    outline: transparent;
    position: relative;
    font-family: "Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;
    -webkit-font-smoothing: antialiased;
    font-size: $ms-font-size-m;
    font-weight: $ms-font-weight-regular;
    border-width: 0;
    text-align: center;
    cursor: pointer;
    display: inline-block;
    padding: 0 16px;

    .label {
      font-weight: $ms-font-weight-semibold;
      font-size: $ms-font-size-m;
      height: 32px;
      line-height: 32px;
      margin: 0 4px;
      vertical-align: top;
      display: inline-block;
    }
  }
}



Conclusion

When you install a WebPart to a MS Teams Tab, the SASS theme's variables still represent the colors of the applied theme on the Site Collection where the WebPart was deployed.

When a user decides to apply/change a theme on his MS Teams environment, will expect that the WebPart changes its palette, accordantly.

Theme's variables in the SASS file work fine inside a SharePoint site but shouldn't be used in a MS Teams Tab. To keep your WebPart looking good on both environments, you need to separate the styles and add logics to wrap the WebPart zone with specific classes.


Comments

  1. Project Task Management Software is a wonderful way to get help for external resources. The team offered by us are amazing in Project Task Management Software and offer the best to satisfy the clients.

    ReplyDelete
  2. As a Microsoft Dynamics 365 partner, we are able to provide you with an end-to-end business application that connects your core business functions by unifying ERP and CRM with purpose-built apps.

    ReplyDelete
  3. At AlphaBOLD, we consider penetration testing services one of the most important steps in securing your web application.

    ReplyDelete

Post a Comment

Popular posts from this blog

Property Pane dynamic fields

Sharing Dynamic Data between WebParts