Fluent UI and TypeScript using NotePad

If you want to use Office UI Fabric React it makes sense to bundle all the modules together into a single file.
One way of doing this is to use WebPack which has its own development web server.
Before you read this page you should read [[TypeScript > Linking TSX File]]


Generate package.json file

Open File Explorer and browse to the (C:\temp\fabric) folder.
Create a new subfolder called "typescript" (C:\temp\fabric\typescript).
Create a new subfolder called "notepad" (C:\temp\fabric\typescript\notepad).
Open a command prompt (run as admin).
Change the folder and initialise npm.

cd c:\temp\fabric\typescript\notepad 
npm init

Press Enter to accept all the defaults.
This will create a "package.json" file in the folder (C:\temp\fabric\typescript\notepad).


Install Webpack

[[more information]]

npm install --save-dev webpack 
npm install --save-dev webpack-cli
npm install --save-dev webpack-dev-server
npm install --save-dev html-webpack-plugin

Install Babel

[[more information]]

npm install --save-dev babel-loader 
npm install --save-dev @babel/core
npm install --save-dev @babel/preset-react
npm install --save-dev @babel/preset-typescript

Install React

[[more information]]

npm install --save-dev react 
npm install --save-dev react-dom

Install Typescript

[[more information]]

npm install --save-dev typescript 
npm install --save-dev ts-loader

Install the typescript type definitions for react.

npm install --save-dev @types/react 

Install the typescript type definitions for react Dom.

npm install --save-dev @types/react-dom 

Install Office UI Fabric React

This module includes the Core Framework.
Install the Office UI Fabric React webpack module.

npm install --save office-ui-fabric-react 

The '--save' switch will add this module as a dependency in the package.json file.


Edit package.json file

Open NotePad++ and drag the "package.json" file on to it.
Change the main parameter from "index.js" to "code/index.tsx".

{ 
  "name": "notepad",
  "version": "1.0.0",
  "description": "",
  "main": "code/index.tsx",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.2.0",
    "@babel/preset-react": "^7.0.0",
    "@babel/preset-typescript": "^7.1.0",
    "@types/react":"^16.7.20",
    "@types/react-dom":^16.0.11",
    "babel-loader": "^8.0.4",
    "html-webpack-plugin": "^2.30.1",
    "react": "^16.6.3",
    "react-dom": "^16.6.3",
    "ts-loader":"^5.3.3",
    "typescript": "^3.2.4",
    "webpack": "^4.27.1",
    "webpack-cli": "^3.1.2"
    "webpack-dev-server": "^3.1.10",
  },
  "dependencies": {
    "office-ui-fabric-react": "^6.111.0"
  }
}

Create index.html

Open File Explorer in the root folder (C:\temp\fabric\typescript\notepad).
Create a new sub folder called "code" (C:\temp\fabric\typescript\notepad\code).
Create a NotePad file with the following contents and save it as 'index.html'.
This file DOES NOT contain a link to webpackbundle.js.

<!DOCTYPE html> 
<html>
<body>
<h3>BetterSolutions.com</h3>
<div id="app"></div>
</body>
</html>

Create index.tsx file

Open File Explorer in the root folder (C:\temp\fabric\typescript\notepad\code).
Create a NotePad file with the following contents and save it as "index.tsx".
This file contains ES 2015 javascript and TSX code that uses React.
This file creates a React component called BETButtonPrimary which creates a Fabric UI button with an onClick event.
This file creates a React component called BETButtonWithDialog which creates a button that displays a dialog box.
Both these components are classes that use Interfaces.

import * as React from 'react';    
import * as ReactDOM from 'react-dom';

import { PrimaryButton, DefaultButton, ButtonType } from 'office-ui-fabric-react/lib/Button';
import { Dialog, DialogType, DialogFooter } from 'office-ui-fabric-react/lib/Dialog';

interface IProps_BETButtonPrimary {
    pButtonLabel: string,
    pOnClick: (event: React.MouseEvent<HTMLDivElement>) => void
}
export class BETButtonPrimary extends React.Component
   < IProps_BETButtonPrimary >
{
    constructor(props : IProps_BETButtonPrimary) {
        super(props);
    }

    render() {
        return (
            <div id='content-main'>
                 <PrimaryButton
                     className='normal-button'
                     buttonType={ ButtonType.hero }
                     onClick={ this.props.pOnClick }
                 >
                    { this.props.pButtonLabel }
                 </PrimaryButton>
            </div>
        );
    }
}

interface IProps_BETButtonWithDialog {
}
interface IState_BETButtonWithDialog {
   sHideDialog: boolean
}
export class BETButtonWithDialog extends React.Component
   < IProps_BETButtonWithDialog , IState_BETButtonWithDialog >
{
  constructor(props: IProps_BETButtonWithDialog) {
    super(props);
    this.state = {
      sHideDialog: true
    };
  }

  method_ShowDialog = (event: React.MouseEvent<HTMLDivElement>) : void => {
    this.setState({ sHideDialog: false });
  };

  method_SaveDialog = (): void => {
    this.setState({ sHideDialog: true });
  };

  method_CloseDialog = (): void => {
    this.setState({ sHideDialog: true });
  };

    render() {
        return (
            <div className='ms-welcome'>
                <BETButtonPrimary
                    pButtonLabel='Press This Button'
                    pOnClick={ this.method_ShowDialog }
                />

        <Dialog
          hidden={ this.state.sHideDialog }
          onDismiss={ this.method_CloseDialog }
          dialogContentProps={{
            type: DialogType.normal,
            title: 'Dialog Box Title',
            subText: 'Dialog Box Long Message.'
          }}
          modalProps={{
            isBlocking: true,
            containerClassName: 'ms-dialogMainOverride'
          }}
        >
          <DialogFooter>
            <PrimaryButton
               onClick={ this.method_SaveDialog }
               text="Save"
            />
            <DefaultButton
               onClick={ this.method_CloseDialog }
               text="Cancel"
            />
          </DialogFooter>
        </Dialog>

            </div>
        );
    }
}

ReactDOM.render(
  <BETButtonWithDialog/>,
  document.getElementById('app')
);

Create tsconfig.json

Open File Explorer in the root folder (C:\temp\fabric\typescript\notepad).
Create a NotePad file with the following contents and save it as "tsconfig.json".

{ 
    "compilerOptions": {
        "module": "commonjs",
        "target": "es6",
        "noImplicitAny": false,
        "sourceMap": false,
        "outDir": "build",
        "jsx": "react"
    },
    "exclude": [
        "node_modules"
    ]
}

Create webpack.config.js

Open File Explorer in the root folder (C:\temp\fabric\typescript\notepad).
Create a NotePad file with the following content.
The 'html'webpack-plugin' tells webpack to bundle all the html files into a single file called "index.html".
This file tells webpack to include an additional rule that uses 'ts-loader'.
This file tells webpack to include an additional output path and subfolder 'build'.

var HTMLWebpackPlugin = require('html-webpack-plugin');   
var HTMLWebpackPluginConfig = new HTMLWebpackPlugin({
   template: __dirname + '/code/index.html',
   filename: 'index.html',
   inject: 'body'
});

module.exports = {
  resolve: {
    extensions: ['.tsx','.js']
  },
   entry: __dirname + '/code/index.tsx',
   output: {
      filename: 'webpackbundle.js',
      path: __dirname + '/build'
   },
   module: {
      rules: [
          {
             test: /.tsx$/,
             exclude: /node_modules/,
             use: {
                loader: 'babel-loader',
                options: {
                   presets: ['@babel/react']
                }
             }
          } ,
          {
             test: /.tsx$/,
             exclude: /node_modules/,
             use: {
                loader: 'ts-loader',
             }
          }

      ]
   },
   plugins: [HTMLWebpackPluginConfig]
};

Launch Browser

There is no more configuration that needs to be done.
You are now in a position to launch webpack and start the local development server.
Open a command prompt (run as admin).
Change to the corresponding folder and execute the following 2 commands.

node ./node_modules/webpack/bin/webpack --mode development 
node ./node_modules/webpack-dev-server/bin/webpack-dev-server --mode development

Open your browser and display the URL - localhost:8080
Pressing "Ctrl + C" will stop the process from running in the command prompt.


© 2024 Better Solutions Limited. All Rights Reserved. © 2024 Better Solutions Limited TopPrevNext