Default

Loading interactive example. Full source is available below.

View example source
Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { ProgressBarProps } from "@coreai-ds/react-components";
import type { JSXElement } from "@coreai-ds/react-components";
import { Field } from "@coreai-ds/react-components";
import { ProgressBar } from "@coreai-ds/react-components";
import * as React from 'react';

export const Default = (props: Partial<ProgressBarProps>): JSXElement => {
    return (<Field validationMessage="Default ProgressBar" validationState="none">
      <ProgressBar {...props} value={0.5}/>
    </Field>);
};

export default Default;

Resources

Best practices

Do

  • Use determinate progress bars whenever progress can be measured.
  • Combine related steps into one continuously advancing progress bar.
  • Use brief, descriptive -ing verbs followed by an ellipsis in status text.

Don't

  • Interrupt an indeterminate progress bar in the middle of an animation.
  • Include time estimates unless they are reliable.
  • Add a period to the progress label.

Behavior and states

  • Progress bars can be either determinate or indeterminate, depending on the needs of your app and the capabilities of the technology you’re building on.
  • Use determinate progress bars whenever possible. They communicate status and assure people things are still working.
  • Only use indeterminate progress bars for short tasks.
  • If enough data is gathered after a task starts and it becomes possible to communicate how much time is left, switch to a determinate progress bar.
  • Progress bars should only be used for tasks that take longer than a second.
  • If you’re loading new content with a known structure that doesn’t block the UI, try a skeleton.
API referenceGenerated CoreAI prop and type summaries

API

Generated CoreAI prop summaries, not replacement type declarations. Most native DOM/event and ARIA props are omitted. ? means optional; JSDoc shows defaults, deprecations, and conditional requirements. Defaults assume the standard CoreAI provider.

ProgressBar API

A ProgressBar bar shows the progression of a task.

interface ProgressBarProps {
  as?: "div";

  /**
   * The filled portion of the ProgressBar bar. Animated in the indeterminate state, when no value is provided.
   */
  bar?: NonNullable<WithSlotShorthandValue<{ as?: "div"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & { ref?: ((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null; }, "children"> & { children?: any; }> | null> | undefined;

  children?: any;

  className?: string;

  /**
   * The status of the ProgressBar bar. Changes the color of the bar.
   * @default brand
   */
  color?: string;

  /**
   * Motion slot for the indeterminate animation. Pass `null` to disable the animation.
   */
  indeterminateMotion?: MotionSlotProps | null;

  /**
   * The maximum value, which indicates the task is complete.
   * The ProgressBar bar will be full when `value` equals `max`.
   * @default 1
   */
  max?: number;

  ref?: Ref<HTMLDivElement>;

  /**
   * The shape of the bar and track.
   * @default rounded
   */
  shape?: "rounded" | "square";

  style?: CSSProperties;

  /**
   * The thickness of the ProgressBar bar
   * @default medium
   */
  thickness?: "medium" | "large";

  /**
   * A decimal number between `0` and `1` (or between `0` and `max` if given),
   * which specifies how much of the task has been completed.
   *
   * If `undefined` (default), the ProgressBar will display an **indeterminate** state.
   */
  value?: number;
}

Implementation

CoreAI 0.12.0; Fluent 9.74.9.

Setup and dependencies.

Import components from @coreai-ds/react-components. CoreAI guidance above takes precedence over API demonstration examples.

Color

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { Field } from "@coreai-ds/react-components";
import { ProgressBar } from "@coreai-ds/react-components";
import * as React from 'react';

const useStyles = makeStyles({
    container: {
        display: 'flex',
        flexDirection: 'column',
        rowGap: '20px',
    },
});

export const Color = (): JSXElement => {
    const styles = useStyles();
    return (<div className={styles.container}>
      <Field validationMessage="Error ProgressBar">
        <ProgressBar value={0.75} color="error"/>
      </Field>

      <Field validationMessage="Warning ProgressBar" validationState="warning">
        <ProgressBar value={0.95} color="warning"/>
      </Field>

      <Field validationMessage="Success ProgressBar" validationState="success">
        <ProgressBar value={1} color="success"/>
      </Field>
    </div>);
};

export default Color;

Indeterminate

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { Field } from "@coreai-ds/react-components";
import { ProgressBar } from "@coreai-ds/react-components";
import * as React from 'react';

export const Indeterminate = (): JSXElement => {
    return (<Field validationMessage="Indeterminate ProgressBar" validationState="none">
      <ProgressBar />
    </Field>);
};

export default Indeterminate;

Max

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import * as React from 'react';
import { Field } from "@coreai-ds/react-components";
import { ProgressBar } from "@coreai-ds/react-components";

const intervalIncrement = 1;

const intervalDelay = 100;

export const Max = (): JSXElement => {
    const [value, setValue] = React.useState(0);
    React.useEffect(() => {
        const id = setInterval(() => {
            setValue(value < 42 ? intervalIncrement + value : 0);
        }, intervalDelay);
        return () => {
            clearInterval(id);
        };
    });
    return (<Field validationMessage={`There have been ${value} files downloaded`} validationState="none">
      <ProgressBar max={42} value={value}/>
    </Field>);
};

export default Max;

Motion Custom

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { Field } from "@coreai-ds/react-components";
import { ProgressBar } from "@coreai-ds/react-components";
import { createMotionComponent } from "@coreai-ds/react-components";
import * as React from 'react';

// A custom motion component that swings between left and right, instead of always moving to the right.
// The reduced motion version of the animation moves more slowly, with no acceleration, using a gentler gradient.
const SwingMotion = createMotionComponent({
    // translate percentages are relative to the element's own width, not the container's.
    // The indeterminate bar is ~33% the width of its container, so:
    //   translate: '-100%' === left: '-33%' (one bar-width off-screen to the left)
    //   translate: '300%'  === left: '100%' (3 × bar-width ≈ full container width, off-screen to the right)
    keyframes: [{ translate: '-100%' }, { translate: '300%' }],
    duration: 2000,
    easing: 'ease-in-out',
    direction: 'alternate', // loop by reversing direction
    iterations: Infinity,
    reducedMotion: {
        // The gradient bar is 100% of the container for reduced motion, which is 3x wider
        keyframes: [{ translate: '-100%' }, { translate: '100%' }],
        duration: 6000, // slower speed
        easing: 'linear', // no acceleration
    },
});

export const MotionCustom = (): JSXElement => (<Field validationMessage="Custom indeterminate animation" validationState="none">
    <ProgressBar indeterminateMotion={{
        children: (_, motionProps) => <SwingMotion {...motionProps}/>,
    }}/>
  </Field>);

export default MotionCustom;

Shape

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { Field } from "@coreai-ds/react-components";
import { ProgressBar } from "@coreai-ds/react-components";
import * as React from 'react';

const useStyles = makeStyles({
    container: {
        margin: '20px 0px',
    },
});

export const Shape = (): JSXElement => {
    const styles = useStyles();
    return (<div>
      <Field validationMessage="Rounded ProgressBar" validationState="none">
        <ProgressBar className={styles.container} shape="rounded" thickness="large" value={0.5}/>
      </Field>
      <Field validationMessage="Square ProgressBar" validationState="none">
        <ProgressBar className={styles.container} shape="square" thickness="large" value={0.5}/>
      </Field>
    </div>);
};

export default Shape;

Thickness

Loading interactive example. Full source is available below.

Download source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { Field } from "@coreai-ds/react-components";
import { ProgressBar } from "@coreai-ds/react-components";
import * as React from 'react';

const useStyles = makeStyles({
    container: {
        margin: '20px 0px',
    },
});

export const Thickness = (): JSXElement => {
    const styles = useStyles();
    return (<div>
      <Field validationMessage="Medium ProgressBar" validationState="none">
        <ProgressBar className={styles.container} thickness="medium" value={0.7}/>
      </Field>

      <Field validationMessage="Large ProgressBar" validationState="none">
        <ProgressBar className={styles.container} thickness="large" value={0.7}/>
      </Field>
    </div>);
};

export default Thickness;