Default

Loading interactive example. Full source is available below.

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

import { Button } from "@coreai-ds/react-components";
import * as React from 'react';

export const Default = () => <Button>Example</Button>;

export default Default;

Resources

Best practices

Do

  • Use buttons for actions.
  • Use the attention-grabbing primary button to communicate the most recommended action on the page.
  • Always give the primary button action prominent placement, either on top of or to the left of other actions. In right-to-left languages, primary button placement will be on the right.
  • Use active language that reflects the action that will happen next.
  • Be brief. Usually a single verb is best, but include a noun if it increases clarity.
  • Use sentence case and no end punctuation.
  • Use only one primary button per page.

Don't

  • Hide buttons.
  • Use articles such as “a,” “an,” or “the.”
  • Use punctuation.
  • Use an icon in a call-to-action button.

Behavior and states

  • A standard button initiates a single action or event.
  • A toggle button switches a state between on and off. Its rest state indicates off, while its selected state indicates on.
  • Button and compound button types can have toggle behavior.
  • Toggle buttons are typically used in toolbars. In other scenarios like a settings panel, use a switch to let someone choose between two mutually exclusive options and trigger an immediate change.
  • If you need to navigate to another place, try a link 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.

Button API

interface ButtonProps {
  /**
   * A button can have its content and borders styled for greater emphasis or to be subtle.
   * - 'secondary' (default): Gives emphasis to the button in such a way that it indicates a secondary action.
   * - 'primary': Emphasizes the button as a primary action.
   * - 'outline': Removes background styling.
   * - 'subtle': Minimizes emphasis to blend into the background until hovered or focused.
   * - 'transparent': Removes background and border styling.
   * @default 'secondary'
   */
  appearance?: "outline" | "subtle" | "secondary" | "primary" | "transparent";

  as?: "a" | "button";

  children?: any;

  className?: string;

  /**
   * A button can show that it cannot be interacted with.
   * @default false
   */
  disabled?: boolean;

  /**
   * When set, allows the button to be focusable even when it has been disabled.
   * This is used in scenarios where it is important to keep a consistent tab order
   * for screen reader and keyboard users. The primary example of this
   * pattern is when the disabled button is in a menu or a commandbar and is seldom used for standalone buttons.
   * When set, allows the button to be focusable even when it has been disabled. This is used in scenarios where it
   * is important to keep a consistent tab order for screen reader and keyboard users. The primary example of this
   * pattern is when the disabled button is in a menu or a commandbar and is seldom used for standalone buttons.
   * @default false
   * false
   */
  disabledFocusable?: boolean;

  /**
   * Icon that renders either before or after the `children` as specified by the `iconPosition` prop.
   */
  icon?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;

  /**
   * A button can format its icon to appear before or after its content.
   * @default 'before'
   */
  iconPosition?: "before" | "after";

  ref?: Ref<HTMLAnchorElement | HTMLButtonElement>;

  /**
   * A button can be rounded, circular, or square.
   * @default 'circular'
   */
  shape?: "circular" | "rounded" | "square";

  /**
   * A button supports different sizes.
   * @default 'medium'
   */
  size?: "small" | "medium" | "large";

  style?: CSSProperties;
}

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.

Appearance

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 { Button } from "@coreai-ds/react-components";
import { CalendarMonthRegular } from "@fluentui/react-icons";
import { bundleIcon } from "@fluentui/react-icons";
import { CalendarMonthFilled } from "@fluentui/react-icons";
import * as React from 'react';

const useStyles = makeStyles({
    wrapper: {
        columnGap: '15px',
        display: 'flex',
    },
});

const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular);

export const Appearance = (): JSXElement => {
    const styles = useStyles();
    return (<div className={styles.wrapper}>
      <Button icon={<CalendarMonthRegular />}>Default</Button>
      <Button appearance="primary" icon={<CalendarMonthRegular />}>
        Primary
      </Button>
      <Button appearance="outline" icon={<CalendarMonth />}>
        Outline
      </Button>
      <Button appearance="subtle" icon={<CalendarMonth />}>
        Subtle
      </Button>
      <Button appearance="transparent" icon={<CalendarMonth />}>
        Transparent
      </Button>
    </div>);
};

export default Appearance;

Disabled

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 { Button } from "@coreai-ds/react-components";
import * as React from 'react';

const useStyles = makeStyles({
    innerWrapper: {
        columnGap: '15px',
        display: 'flex',
    },
    outerWrapper: {
        display: 'flex',
        flexDirection: 'column',
        rowGap: '15px',
    },
});

export const Disabled = (): JSXElement => {
    const styles = useStyles();
    return (<div className={styles.outerWrapper}>
      <div className={styles.innerWrapper}>
        <Button>Enabled state</Button>
        <Button disabled>Disabled state</Button>
        <Button disabledFocusable>Disabled focusable state</Button>
      </div>
      <div className={styles.innerWrapper}>
        <Button appearance="primary">Enabled state</Button>
        <Button appearance="primary" disabled>
          Disabled state
        </Button>
        <Button appearance="primary" disabledFocusable>
          Disabled focusable state
        </Button>
      </div>
    </div>);
};

export default Disabled;

Icon

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 { Button } from "@coreai-ds/react-components";
import { CalendarMonthRegular } from "@fluentui/react-icons";
import { Tooltip } from "@coreai-ds/react-components";
import * as React from 'react';

const useStyles = makeStyles({
    wrapper: {
        columnGap: '15px',
        display: 'flex',
    },
});

export const Icon = (): JSXElement => {
    const styles = useStyles();
    return (<div className={styles.wrapper}>
      <Button icon={<CalendarMonthRegular />}>With calendar icon before contents</Button>
      <Button icon={<CalendarMonthRegular />} iconPosition="after">
        With calendar icon after contents
      </Button>
      <Tooltip content="With calendar icon only" relationship="label">
        <Button icon={<CalendarMonthRegular />}/>
      </Tooltip>
    </div>);
};

export default Icon;

Loading

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 { tokens } from "@coreai-ds/react-components";
import { buttonClassNames } from "@coreai-ds/react-components";
import * as React from 'react';
import { useTimeout } from "@fluentui/react-utilities";
import { Spinner } from "@coreai-ds/react-components";
import { CheckmarkFilled } from "@fluentui/react-icons";
import { Button } from "@coreai-ds/react-components";

const useStyles = makeStyles({
    wrapper: {
        columnGap: '15px',
        display: 'flex',
    },
    buttonNonInteractive: {
        backgroundColor: tokens.colorNeutralBackground1,
        border: `${tokens.strokeWidthThin} solid ${tokens.colorNeutralStroke1}`,
        color: tokens.colorNeutralForeground1,
        cursor: 'default',
        pointerEvents: 'none',
        [`& .${buttonClassNames.icon}`]: {
            color: tokens.colorStatusSuccessForeground1,
        },
    },
});

type LoadingState = 'initial' | 'loading' | 'loaded';

export const Loading = (): JSXElement => {
    const styles = useStyles();
    const [loadingState, setLoadingState] = React.useState<LoadingState>('initial');
    const [setTimeout, cancelTimeout] = useTimeout();
    const onButtonClick = () => {
        setLoadingState('loading');
        setTimeout(() => setLoadingState('loaded'), 5000);
    };
    const buttonContent = loadingState === 'loading' ? 'Loading' : loadingState === 'loaded' ? 'Loaded' : 'Start loading';
    const buttonIcon = loadingState === 'loading' ? <Spinner size="tiny"/> : loadingState === 'loaded' ? <CheckmarkFilled /> : null;
    const buttonClassName = loadingState === 'initial' ? undefined : styles.buttonNonInteractive;
    const onResetButtonClick = () => {
        cancelTimeout();
        setLoadingState('initial');
    };
    return (<div className={styles.wrapper}>
      <Button className={buttonClassName} disabledFocusable={loadingState !== 'initial'} icon={buttonIcon} onClick={onButtonClick}>
        {buttonContent}
      </Button>
      <Button onClick={onResetButtonClick}>Reset loading state</Button>
    </div>);
};

export default Loading;

Shape

Loading interactive example. Full source is available below.

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

import { Button } from "@coreai-ds/react-components";
import * as React from 'react';

export const Shape = () => (<div style={{ display: 'flex', gap: '15px' }}>
      <Button shape="rounded">Rounded</Button>
      <Button shape="circular">Circular</Button>
      <Button shape="square">Square</Button>
    </div>);

export default Shape;

Size

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 { Button } from "@coreai-ds/react-components";
import { CalendarMonthRegular } from "@fluentui/react-icons";
import { Tooltip } from "@coreai-ds/react-components";
import * as React from 'react';

const useStyles = makeStyles({
    innerWrapper: {
        alignItems: 'start',
        columnGap: '15px',
        display: 'flex',
    },
    outerWrapper: {
        display: 'flex',
        flexDirection: 'column',
        rowGap: '15px',
        minWidth: 'min-content',
    },
});

export const Size = (): JSXElement => {
    const styles = useStyles();
    return (<div className={styles.outerWrapper}>
      <div className={styles.innerWrapper}>
        <Button size="small">Small</Button>
        <Button size="small" icon={<CalendarMonthRegular />}>
          Small with calendar icon
        </Button>
        <Tooltip content="Small with calendar icon only" relationship="label">
          <Button size="small" icon={<CalendarMonthRegular />}/>
        </Tooltip>
      </div>
      <div className={styles.innerWrapper}>
        <Button>Medium</Button>
        <Button icon={<CalendarMonthRegular />}>Medium with calendar icon</Button>
        <Tooltip content="Medium with calendar icon only" relationship="label">
          <Button icon={<CalendarMonthRegular />}/>
        </Tooltip>
      </div>
      <div className={styles.innerWrapper}>
        <Button size="large">Large</Button>
        <Button size="large" icon={<CalendarMonthRegular />}>
          Large with calendar icon
        </Button>
        <Tooltip content="Large with calendar icon only" relationship="label">
          <Button size="large" icon={<CalendarMonthRegular />}/>
        </Tooltip>
      </div>
    </div>);
};

export default Size;

Subtle Content Alignment

Loading interactive example. Full source is available below.

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

import { Text } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import * as React from 'react';

export const SubtleContentAlignment = () => {
    const styles = /* css */ `
      .button-example__aligned-action {
        margin-inline: calc(-1 * var(--spacingHorizontalS));
      }
    `;
    return (<>
        <style>{styles}</style>
        <Text as="h2" block preset="heading4" foreground={1}>
          Aligning subtle button content to surrounding text
        </Text>
        <Text as="p" block>
          Subtle and transparent buttons keep the same horizontal padding as filled buttons, so
          their visible content sits inset from surrounding text. A matching negative inline margin
          optically aligns the button's content to this paragraph's edge while keeping the full
          padded hit target for click and focus.
        </Text>
        <Button appearance="subtle" size="small" className="button-example__aligned-action">
          Aligned action
        </Button>
      </>);
};

export default SubtleContentAlignment;

With Long Text

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 { Button } from "@coreai-ds/react-components";
import * as React from 'react';

const useStyles = makeStyles({
    longText: {
        width: '280px',
    },
    wrapper: {
        alignItems: 'center',
        columnGap: '15px',
        display: 'flex',
        minWidth: 'min-content',
    },
});

export const WithLongText = (): JSXElement => {
    const styles = useStyles();
    return (<div className={styles.wrapper}>
      <Button>Short text</Button>
      <Button className={styles.longText}>Long text wraps after it hits the max width of the component</Button>
    </div>);
};

export default WithLongText;