Category: Office UI Fabric

  • Accordion in Fluent UI / Office UI Fabric

    Accordion in Fluent UI / Office UI Fabric

    Fluent UI / Office UI Fabric does not provide any Accordion control. But you can create your Accordion using the Fluent UI controls itself. Below is the code for Accordion control that I have created in React. You can also see it action on CodeSandbox.

    import * as React from "react";
    import {
      DefaultPalette,
      AnimationClassNames
    } from "office-ui-fabric-react/lib/Styling";
    import {
      IconButton,
      initializeIcons,
      Stack,
      IStackItemStyles,
      IStackStyles
    } from "office-ui-fabric-react";
    
    initializeIcons();
    
    export class Accordion extends React.Component<IAccordionProps, {}> {
      private accordionHeader: IStackItemStyles = {
        root: {
          background: DefaultPalette.neutralLighter,
          padding: 5,
          cursor: "pointer"
        }
      };
      private accordion: IStackStyles = {
        root: {
          borderStyle: "solid",
          borderWidth: 1,
          borderColor: DefaultPalette.neutralTertiary
        }
      };
      private accordionConent: IStackStyles = {
        root: {
          padding: 10
        }
      };
    
      constructor(props: IAccordionProps, public state: any) {
        super(props);
    
        this.state = {
          content: false
        };
      }
    
      private showContent = (e) => {
        this.setState({
          content: !this.state.content
        });
      };
    
      public componentDidMount() {}
    
      public render(): React.ReactElement<IAccordionProps> {
        return (
          <>
            <Stack horizontal={false} styles={this.accordion}>
              <Stack.Item styles={this.accordionHeader}>
                <Stack horizontal={true} onClick={this.showContent}>
                  <Stack.Item>
                    <IconButton
                      iconProps={{
                        iconName: this.state.content
                          ? "ChevronDown"
                          : "ChevronRight"
                      }}
                    />
                  </Stack.Item>
                  <Stack.Item align="center">{this.props.header}</Stack.Item>
                </Stack>
              </Stack.Item>
              {this.state.content && (
                <Stack.Item
                  className={AnimationClassNames.slideDownIn20}
                  styles={this.accordionConent}
                >
                  {this.props.children}
                </Stack.Item>
              )}
            </Stack>
          </>
        );
      }
    }
    
    interface IAccordionProps {
      header: string;
    }

    You can use the control in your code with below sample code.

    <Accordion header="Lorem Ipsum">
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
          tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
          veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
          commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
          velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
          cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id
          est laborum.
        </Accordion>
  • Animations in Office UI Fabric

    Working on an assignment and rummaging through Google search results I ran into this page. Apparently, Office UI Fabric supports animation. But the documentation does not list out any details as to what classes to use, neither are there any examples. More search and I find this issue having similar complaint as mine. The issue also lists a sample code using CSS-in-JS to implement animation. Lets take a look.

    First lets import animation modules from Office UI Fabric.

    import { AnimationStyles, AnimationClassNames, AnimationVariables } from 'office-ui-fabric-react/lib/Styling';

    Lets take a look at what each modules does.

    AnimationStyles

    This module contains all the standard Office UI Fabric animations as JSON objects with predefined keyframes. Below are the styles we can use.

    slideRightIn10
    slideRightIn20
    slideRightIn40
    slideRightIn400
    slideLeftIn10
    slideLeftIn20
    slideLeftIn40
    slideLeftIn400
    slideUpIn10
    slideUpIn20
    slideDownIn10
    slideDownIn20
    slideRightOut10
    slideRightOut20
    slideRightOut40
    slideRightOut400
    slideLeftOut10
    slideLeftOut20
    slideLeftOut40
    slideLeftOut400
    slideUpOut10
    slideUpOut20
    slideDownOut10
    slideDownOut20
    scaleUpIn100
    scaleDownIn100
    scaleUpOut103
    scaleDownOut98
    fadeIn100
    fadeIn200
    fadeIn400
    fadeIn500
    fadeOut100
    fadeOut200
    fadeOut400
    fadeOut500
    rotate90deg
    rotateN90deg

    To use AnimationStyles you use the CSS-in-JS approach with the JavaScript spread operator.

    const btnStyleSlideIn: IButtonStyles = {
        root: {
            ...AnimationStyles.slideLeftIn400
        }
    };

    Below is the sample React code implementation.

    public render(): React.ReactElement {
        const btnStyleSlideIn: IButtonStyles = {
            root: {
                ...AnimationStyles.slideLeftIn400
            }
        };
        return (<>
            <PrimaryButton text="Animate"
                onClick={(_) => {
                    this.setState({
                        enableAnimation: true
                    }, () => {
                        setTimeout(() => {
                            this.setState({
                                enableAnimation: false
                            });
                        }, 2000)
                    });
                }}
                disabled={this.state.enableAnimation} />
            <Button text="I am sliding in to left"
                iconProps={{ iconName: 'ChevronLeft' }}
                styles={this.state.enableAnimation ? btnStyleSlideIn : {}} />
        </>);
    }

    AnimationClassNames

    This module contains all the standard Office UI Fabric animation class names. It is similar to AnimationStyles but it just gives you class names rather than the JSON object. Below is the sample React code implementation.

    public render(): React.ReactElement {
        return (<>
            <PrimaryButton text="Animate"
                onClick={(_) => {
                    this.setState({
                        enableAnimation: true
                    }, () => {
                        setTimeout(() => {
                            this.setState({
                                enableAnimation: false
                            });
                        }, 2000)
                    });
                }}
                disabled={this.state.enableAnimation} />
            <Button text="I am sliding in to left, using CSS class"
                iconProps={{ iconName: 'ChevronLeft' }}
                className={this.state.enableAnimation ? AnimationClassNames.slideLeftIn400 : ""} />
        </>);
    }

    AnimationVariables

    This module exports duration values and easing functions which can be used in custom animations. You can use these values in your animations. If you log it to browser console you should see something similar to below output.

    {
        durationValue1: "0.167s",
        durationValue2: "0.267s",
        durationValue3: "0.367s",
        durationValue4: "0.467s",
        easeFunction1: "cubic-bezier(.1,.9,.2,1)",
        easeFunction2: "cubic-bezier(.1,.25,.75,.9)"
    }

    Below is a sample React code implementation.

    public render(): React.ReactElement {
        const kf: string = keyframes({
            "12.5%": { left: -5 },
            "25%": { left: 5 },
            "37.5%": { left: -2.5 },
            "50%": { left: 2.5 },
            "62.5%": { left: -1 },
            "75%": { left: 1 }
        });
        
        const btnStyleShakeIt: IButtonStyles = {
            root: {
                animationDuration: AnimationVariables.durationValue1, // Use Office UI Fabric animation duration
                animationName: kf
            }
        };
    
        return (<>
            <PrimaryButton text="Animate"
                onClick={(_) => {
                    this.setState({
                        enableAnimation: true
                    }, () => {
                        setTimeout(() => {
                            this.setState({
                                enableAnimation: false
                            });
                        }, 2000)
                    });
                }}
                disabled={this.state.enableAnimation} />
            <Button text="Shake it!"
                styles={this.state.enableAnimation ? btnStyleShakeIt : {}} />
        </>);
    }