Implement React Elastic Carousel With SharePoint Framework (SPFx)

Introduction

We often get an inquiry about  a scrollable carousel with only sample text and description for a SharePoint modern intranet portal. This will be useful to inform employees about upcoming events, holidays, or incidents that are  related to infra or network outages.

There are many components available that are built on rRact but the majority of them follow the specific content pattern which needs to pass to make it live. Image URL or Image source is a primary example but, in this requirement, image is not required. So we do have another option which will be covered in this article.

In this article, we will learn how to use react elastic carousel with SPFx solution and deploy it on the SharePoint site.

How to make changes in CSS and override existing component CSS of next and previous buttons:

Prerequisites

  1. Install Node js 
  2. Install Yo
  3. Install Gulp
  4. Install template @microsoft/sharepoint to create new solution.
  5. SharePoint list with two columns,

    Name , Description
    Name : Name of the event
    Description : Store the description of the particular event.

Click here to start how to set up the SPFx development environment.

Click here to start how to add a column to the SharePoint list.

I am assuming that the SPFx environment is set up on your end.

Create Webpart

Run the below commands in sequence to create an SPFx solution.

Open the command prompt and create a directory where you want to make the solution. 

  1. md reactelasticdemo
  2. cd reactelasticdemo

Create SPFx solution

  1. yo @microsoft/sharepoint

Select the below values to create a solution and webpart.

Once all options are selected successfully in the wizard, it will take some time to create a solution structure.

Once solution is created then you can open code in visual studio code by code.

Impliment react elastic carousel with SharePoint Framework

You can see the below solution structure.

Impliment react elastic carousel with SharePoint Framework

Install Required Packages

Let us install required npm packages from npm

npm i react-elastic-carousel

This package is used to render carousel based on the records which will get from SharePoint list. 

react-elastic-carousel is using styled-components for styling, this means that you should install it as well:

npm install –save styled-components

npm install @pnp/sp

This package is used to communicate with SharePoint list items.

Create Service Provider Class

We will write all methods or I can say rest calls which will useful to get records from SharePoint list and that will be called from our react component.

Create a new folder call "Services" inside "/src/".

As shown in the  image, Create a new file @ "src/Services/SPService.ts".

Add the below code to SPService.ts file,

import "@pnp/sp/webs";
import "@pnp/sp/lists";
import "@pnp/sp/items";
import { Web } from "@pnp/sp/webs";
export class SPService {
    private web;
    constructor(url: string) {
        this.web = Web(url);
    }

    /**
    * Get SP Items from SharePoint list
    * @param list Name provide list name. Please make sure that it should not list internal name
    * @param filter provide filter string if needed
    * @returns
    */
    public async getSPItems(listName: string, filter?: string) {

        let items = await this.web.lists.getByTitle(listName).
            items.filter(filter).
            getAll();

        return items;

    }
}

Initilize SP object of PnP Package

Open your webpart file from solution which is existed at "src\webparts\elasticSpFxReact.ts"

Add the below code to it.

Import PnP package refrence to top section of the page.

import { sp } from "@pnp/sp";

Add the below code in "src\webparts\elasticSpFxReact.ts" file

/**
   * pass current webpart context to SP object of PnP
   * @returns 
   */
    protected onInit(): Promise<void> {
      return super.onInit().then(_ => {
        sp.setup({
          spfxContext: this.context
        });
      });
    }

Create State Interface

Create a new file caled "IElasricSPFxReactState.ts" at "\src\webparts\elasticSpFxReact\components".

Add the below code to it which will be useful to manage states in react component.

export interface IElasricSPFxReactState{
    loading:boolean;
    items:any[] | any;
    selectedTitle:string;
    selectedDescription:string;
}

Update Props Interface

Open props file which is located at "\src\webparts\elasticSpFxReact\components\IElasricSPFxReactProps.ts" and copy below code to it.

export interface IElasticSpFxReactProps {
  description: string;
  siteURL:string;
}

Update code to call React Component from Webpart file.

Open file ElasticSpFxReactWebPart.ts file which is located to "src\webparts\elasticSpFxReact\".

Replace below code to to Render method.

 const element: React.ReactElement<IElasticSpFxReactProps> = React.createElement(
      ElasticSpFxReact,
      {
        description: this.properties.description,
        siteURL:this.context.pageContext.site.absoluteUrl
      }
    );

    ReactDom.render(element, this.domElement);

Create React Component with elastic carousel

Do the addition of below code in compoenent file at "src\webparts\elasticSpFxReact\components\ElasticSpFxReact.tsx."

import * as React from 'react';
import styles from './ElasticSpFxReact.module.scss';
import { IElasticSpFxReactProps } from './IElasticSpFxReactProps';
import { IElasricSPFxReactState } from "./IElasricSPFxReactState";
import { SPService } from "../../../Services/SPService";
import Carousel from 'react-elastic-carousel';
export default class ElasticSpFxReact extends React.Component<IElasticSpFxReactProps, IElasricSPFxReactState> {
  private _services: SPService = null;
  constructor(props: IElasticSpFxReactProps) {
    super(props);
    this.state = {
      loading: false,
      items: [],
      selectedTitle: '',
      selectedDescription: ''
    };
    this._services = new SPService(this.props.siteURL);
  }

  public componentDidMount() {
    this.getItems();
  }

  public async getItems() {
    await this._services.getSPItems('CustomEvents').then((_items: any) => {
      if (_items.length > 0) {
        this.setState({ items: _items });
      }
    });
  }

  public render(): React.ReactElement<IElasticSpFxReactProps> {

    let events = this.state.items.map((element, index) => {
      return (
        <div style={{ height: "30px", width: "100%", backgroundColor: "red"}}>
          <div id={index}
            style=
            {{
              display: "flex",
              justifyContent: "center",
              alignItems: "center",
              color: "#fff",
              cursor: "pointer",
              fontSize: "1.2em",
              paddingTop:"3px"
            }}>
            {element.Title}
          </div>
        </div>
      );
    });

    return (
      <div className={styles.elasticSpFxReact}>
        <div>
            <div>
              <Carousel
                pagination={false}
                itemsToShow={1}
                itemsToScroll={1}
                isRTL={false}>
                {events}
              </Carousel>
            </div>
          </div>
      </div>
    );
  }
}

Run below commands to check Output,

gulp serve --nobrowser

 Open URL "https://<tenant>.sharepoint.com/sites/<siteName>/_layouts/15/workbench.aspx". Add your webpart by clicking on + Icon.

Below code is to make additional changes to carousel look and feel. Let's get started.

Rendering custom arrow button

You can provide custom arrow button inplace of default one.

Open react component file which is located at "src\webparts\elasticSpFxReact\components\ElasticSpFxReact.tsx"

Inside Render method; copy below code and paste it.

public render(): React.ReactElement<IElasticSpFxReactProps> {

    let events = this.state.items.map((element, index) => {
      return (
        <div style={{ height: "30px", width: "100%", backgroundColor: "red"}}>
          <div id={index}
            style=
            {{
              display: "flex",
              justifyContent: "center",
              alignItems: "center",
              color: "#fff",
              cursor: "pointer",
              fontSize: "1.2em",
              paddingTop:"3px"
            }}>
            {element.Title}
          </div>
        </div>
      );
    });

    const myArrow = ({ type, onClick, isEdge }) => {
      const pointer = type === "PREV" ? '👈' : '👉'
      return (
        <Button onClick={onClick} disabled={isEdge}>
          {pointer}
        </Button>
      )
    }

    return (
      <div className={styles.elasticSpFxReact}>
        <div>
            <div>
              <Carousel
                renderArrow={myArrow}
                pagination={false}
                itemsToShow={1}
                itemsToScroll={1}
                isRTL={false}>
                {events}
              </Carousel>
            </div>
          </div>
      </div>
    );
  }

Run Gulp serve --npbrowser and you will get below output.

Render Pagination

In to <Carousel> component, set pagination = {true}.

Run command Gulp Serve and check output.

Animated Button CSS

Almost every element in react-elastic-carousel has a CSS class with the rec- prefix (rec is short React Elastic Carousel).

Create new file called "SideButton.css".

Add the below code to css file.

/* square buttons */
.rec.rec-arrow {
    border-radius: 0;
}
/* round buttons on hover */
.rec.rec-arrow:hover {
    border-radius: 50%;
}
/* hide disabled buttons */
.rec.rec-arrow:disabled {
    visibility: hidden;
}
/* disable default outline on focused items */
/* add custom outline on focused items */
.rec-carousel-item:focus {
    outline: none;
    box-shadow: inset 0 0 1px 1px lightgrey;
}

Import Sidebutton.css file in reactcompoenent file .

require("./SideButton.css")

Output will be as below,

Conclusion

What we covered and learned in this article.

  • SPFx solution creation with React
  • Call Service Provider methods from Component
  • Call React-Elastic-Carousel component from SPFx react component
  • Button styling and custom render
  • Pagination enabled and disabled
  • Custom CSS on side button

I hope you enjoyed this article.

Happy Coding