Spinner
View .mdSpinners visually communicate that something is processing. They’re used for loading states that take more than a second.
Default
Loading interactive example. Full source is available below.
View example source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { SpinnerProps } from "@coreai-ds/react-components";
import type { JSXElement } from "@coreai-ds/react-components";
import { Spinner } from "@coreai-ds/react-components";
import * as React from 'react';
export const Default = (props: Partial<SpinnerProps>): JSXElement => <Spinner {...props}/>;
export default Default;
Resources
Best practices
Do
- Use a spinner for processing or loading states lasting more than one second.
- Center it over the section that is loading.
- Add a label when the process is expected to exceed three seconds.
Don't
- Let one loading section block interaction with unrelated sections.
- Use a spinner to communicate measurable progress; use a determinate progress bar.
- Use vague status labels.
Behavior and states
- Center the spinner over the section of the page that’s loading.
- A spinner for one loading section shouldn’t block interaction with other sections.
- Use a label when a process will take longer than three seconds.
- Keep spinner labels brief, specific, and three words or less.
- Spinners don’t show how much time is left before the process is done.
- To communicate a more specific status, try a determinate progress bar instead.
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.
Spinner API
Converged Spinner component for the fluentui repo
interface SpinnerProps {
/**
* The appearance of the Spinner.
* @default 'primary'
*/
appearance?: "inverted" | "primary";
as?: "div" | "span";
children?: any;
className?: string;
/**
* Time in milliseconds after component mount before spinner is visible.
* @default 0
*/
delay?: number;
/**
* An optional label for the Spinner.
*/
label?: WithSlotShorthandValue<Omit<ComponentProps<LabelSlots>, "required"> & { disabled?: boolean; required?: boolean | WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null | undefined; }, "children"> & { children?: any; }> | null | undefined; size?: "small" | "medium" | "large" | undefined; weight?: "regular" | "semibold" | undefined; } & RefAttributes<HTMLLabelElement>> | null | undefined;
/**
* Where the label is positioned relative to the Spinner
* @default 'after'
*/
labelPosition?: "above" | "below" | "before" | "after";
ref?: Ref<HTMLSpanElement>;
/**
* The size of the spinner.
* @default 'medium'
*/
size?: "small" | "medium" | "large" | "extra-large" | "tiny" | "extra-small" | "huge" | "extra-tiny";
/**
* The animated spinning ring.
*/
spinner?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;
/**
* The part of the spinner that rotates.
*/
spinnerTail?: NonNullable<WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null> | undefined;
style?: CSSProperties;
}
Implementation
CoreAI 0.12.0; Fluent 9.74.9.
Import components from @coreai-ds/react-components. CoreAI guidance above takes precedence over API demonstration examples.
Appearance
Loading interactive example. Full source is available below.
// 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 { tokens } from "@coreai-ds/react-components";
import { Spinner } from "@coreai-ds/react-components";
import * as React from 'react';
const useStyles = makeStyles({
container: {
'> div': { padding: '20px' },
},
// Inverted Spinners are meant as overlays (e.g., over an image or similar)
// so give it a solid, dark background so it is visible in all themes.
invertedWrapper: {
backgroundColor: tokens.colorBrandBackgroundStatic,
},
});
export const Appearance = (): JSXElement => {
const styles = useStyles();
return (<div className={styles.container}>
<Spinner appearance="primary" label="Primary Spinner"/>
<div className={styles.invertedWrapper}>
<Spinner appearance="inverted" label="Inverted Spinner"/>
</div>
</div>);
};
export default Appearance;
Labels
Loading interactive example. Full source is available below.
// 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 { Spinner } from "@coreai-ds/react-components";
import * as React from 'react';
const useStyles = makeStyles({
container: {
'> div': { padding: '20px' },
},
});
export const Labels = (): JSXElement => {
const styles = useStyles();
return (<div className={styles.container}>
<Spinner labelPosition="before" label="Label Position Before..."/>
<Spinner labelPosition="after" label="Label Position After..."/>
<Spinner labelPosition="above" label="Label Position Above..."/>
<Spinner labelPosition="below" label="Label Position Below..."/>
</div>);
};
export default Labels;
Size
Loading interactive example. Full source is available below.
// 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 { Spinner } from "@coreai-ds/react-components";
import * as React from 'react';
const useStyles = makeStyles({
container: {
'> div': { padding: '20px' },
},
});
export const Size = (): JSXElement => {
const styles = useStyles();
return (<div className={styles.container}>
<Spinner size="extra-tiny" label="Extra Tiny Spinner"/>
<Spinner size="tiny" label="Tiny Spinner"/>
<Spinner size="extra-small" label="Extra Small Spinner"/>
<Spinner size="small" label="Small Spinner"/>
<Spinner size="medium" label="Medium Spinner"/>
<Spinner size="large" label="Large Spinner"/>
<Spinner size="extra-large" label="Extra Large Spinner"/>
<Spinner size="huge" label="Huge Spinner"/>
</div>);
};
export default Size;