# ToggleButton

Button that can be toggled between checked and unchecked states.

## Default

Source: CoreAI.

[Download source](/coreai-design-system/source/examples/components-button-togglebutton--default.tsx)

```tsx
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

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

// Inline wrapper — see CompoundButton.stories.tsx.
export const Default = (props: ToggleButtonProps): JSXElement => (<ToggleButton {...props}>Example</ToggleButton>);

export default Default;
```

## 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.

### ToggleButton API

```ts
interface ToggleButtonProps {
  /**
   * 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";

  /**
   * Defines the controlled checked state of the `ToggleButton`.
   * If passed, `ToggleButton` ignores the `defaultChecked` property.
   * This should only be used if the checked state is to be controlled at a higher level and there is a plan to pass the
   * correct value based on handling `onClick` events and re-rendering.
   * @default false
   */
  checked?: boolean;

  children?: any;

  className?: string;

  /**
   * Defines whether the `ToggleButton` is initially in a checked state or not when rendered.
   * @default false
   */
  defaultChecked?: boolean;

  /**
   * 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";

  /**
   * Defines whether the `ToggleButton` should use the alternate selected styles that have adequate contrast with the rest style
   * @default false
   */
  isAccessible?: boolean;

  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](/coreai-design-system/guides/Package.md).

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

## Accessible Appearance

Source: Fluent, adapted for CoreAI.

Appearance variants with isAccessible set, showing more contrasting colors when checked. The primary variant uses the same colors, but with an inset stroke for the checked state.

This approach is available for when the icon is not used to differentiate checked vs. unchecked states.

[Download source](/coreai-design-system/source/examples/components-button-togglebutton--accessible-appearance.tsx)

```tsx
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

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

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

export const AccessibleAppearance = (): JSXElement => {
    const [checked1, setChecked1] = React.useState(false);
    const [checked2, setChecked2] = React.useState(false);
    const styles = useStyles();
    const toggleChecked = React.useCallback((buttonIndex: number) => {
        switch (buttonIndex) {
            case 1:
                setChecked1(!checked1);
                break;
            case 2:
                setChecked2(!checked2);
                break;
        }
    }, [checked1, checked2]);
    return (<div className={styles.wrapper}>
      <ToggleButton checked={checked1} onClick={() => toggleChecked(1)} isAccessible>
        Default
      </ToggleButton>
      <ToggleButton appearance="primary" checked={checked2} onClick={() => toggleChecked(2)} isAccessible>
        Primary
      </ToggleButton>
      <ToggleButton appearance="outline" onClick={() => toggleChecked(3)} isAccessible>
        Outline
      </ToggleButton>
      <ToggleButton appearance="subtle" isAccessible>
        Subtle
      </ToggleButton>
      <ToggleButton appearance="transparent" isAccessible>
        Transparent
      </ToggleButton>
    </div>);
};

export default AccessibleAppearance;
```

## Appearance

Source: Fluent, adapted for CoreAI.

- `(undefined)`: the toggle button appears with the default style
- `primary`: emphasizes the toggle 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.

[Download source](/coreai-design-system/source/examples/components-button-togglebutton--appearance.tsx)

```tsx
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import * as React from 'react';
import { makeStyles } from "@coreai-ds/react-components";
import { ToggleButton } from "@coreai-ds/react-components";
import { bundleIcon } from "@fluentui/react-icons";
import { CalendarMonthFilled } from "@fluentui/react-icons";
import { CalendarMonthRegular } from "@fluentui/react-icons";

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

const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular);

export const Appearance = (): JSXElement => {
    const [checked1, setChecked1] = React.useState(false);
    const [checked2, setChecked2] = React.useState(false);
    const styles = useStyles();
    const toggleChecked = React.useCallback((buttonIndex: number) => {
        switch (buttonIndex) {
            case 1:
                setChecked1(!checked1);
                break;
            case 2:
                setChecked2(!checked2);
                break;
        }
    }, [checked1, checked2]);
    return (<div className={styles.wrapper}>
      <ToggleButton checked={checked1} icon={checked1 ? <CalendarMonth /> : <CalendarMonthRegular />} onClick={() => toggleChecked(1)}>
        Default
      </ToggleButton>
      <ToggleButton appearance="primary" checked={checked2} icon={checked2 ? <CalendarMonth /> : <CalendarMonthRegular />} onClick={() => toggleChecked(2)}>
        Primary
      </ToggleButton>
      <ToggleButton appearance="outline" icon={<CalendarMonth />} onClick={() => toggleChecked(3)}>
        Outline
      </ToggleButton>
      <ToggleButton appearance="subtle" icon={<CalendarMonth />}>
        Subtle
      </ToggleButton>
      <ToggleButton appearance="transparent" icon={<CalendarMonth />}>
        Transparent
      </ToggleButton>
    </div>);
};

export default Appearance;
```

## Checked

Source: Fluent, adapted for CoreAI.

A toggle button can be checked or unchecked. Unchecked is default.
      If a checked value is given, the button is 'controlled' and will only change state when the
      props value changes.

[Download source](/coreai-design-system/source/examples/components-button-togglebutton--checked.tsx)

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

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

export const Checked = (): JSXElement => {
    const styles = useStyles();
    return (<div className={styles.wrapper}>
      <ToggleButton checked={true}>Controlled checked state</ToggleButton>
      <ToggleButton checked={false}>Controlled unchecked state</ToggleButton>
    </div>);
};

export default Checked;
```

## Disabled

Source: Fluent, adapted for CoreAI.

A toggle button can be `disabled` or `disabledFocusable`.
              `disabledFocusable` 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 toggle button is in a menu or a commandbar and is seldom used for standalone buttons.

[Download source](/coreai-design-system/source/examples/components-button-togglebutton--disabled.tsx)

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

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

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

export default Disabled;
```

## Icon

Source: Fluent, adapted for CoreAI.

The ToggleButton has an `icon` slot that, if specified, renders an icon either `before` or `after` the children, as specified by the `iconPosition` prop.

[Download source](/coreai-design-system/source/examples/components-button-togglebutton--icon.tsx)

```tsx
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import type { JSXElement } from "@coreai-ds/react-components";
import * as React from 'react';
import { makeStyles } from "@coreai-ds/react-components";
import { ToggleButton } from "@coreai-ds/react-components";
import { bundleIcon } from "@fluentui/react-icons";
import { CalendarMonthFilled } from "@fluentui/react-icons";
import { CalendarMonthRegular } from "@fluentui/react-icons";
import { Tooltip } from "@coreai-ds/react-components";

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

const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular);

export const Icon = (): JSXElement => {
    const [checked1, setChecked1] = React.useState(false);
    const [checked2, setChecked2] = React.useState(false);
    const [checked3, setChecked3] = React.useState(false);
    const styles = useStyles();
    const toggleChecked = React.useCallback((buttonIndex: number) => {
        switch (buttonIndex) {
            case 1:
                setChecked1(!checked1);
                break;
            case 2:
                setChecked2(!checked2);
                break;
            case 3:
                setChecked3(!checked3);
                break;
        }
    }, [checked1, checked2, checked3]);
    return (<div className={styles.wrapper}>
      <ToggleButton checked={checked1} icon={checked1 ? <CalendarMonth /> : <CalendarMonthRegular />} onClick={() => toggleChecked(1)}>
        With calendar icon before contents
      </ToggleButton>
      <ToggleButton checked={checked2} icon={checked2 ? <CalendarMonth /> : <CalendarMonthRegular />} iconPosition="after" onClick={() => toggleChecked(2)}>
        With calendar icon after contents
      </ToggleButton>
      <Tooltip content="With calendar icon only" relationship="label">
        <ToggleButton checked={checked3} icon={checked3 ? <CalendarMonth /> : <CalendarMonthRegular />} onClick={() => toggleChecked(3)}/>
      </Tooltip>
    </div>);
};

export default Icon;
```

## Shape

Source: Fluent, adapted for CoreAI.

A toggle button can be rounded, circular, or square.

[Download source](/coreai-design-system/source/examples/components-button-togglebutton--shape.tsx)

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

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

export const Shape = (): JSXElement => {
    const styles = useStyles();
    return (<div className={styles.wrapper}>
      <ToggleButton>Rounded</ToggleButton>
      <ToggleButton shape="circular">Circular</ToggleButton>
      <ToggleButton shape="square">Square</ToggleButton>
    </div>);
};

export default Shape;
```

## Size

Source: Fluent, adapted for CoreAI.

A toggle button supports `small`, `medium` and `large` size. Default size is `medium`.

[Download source](/coreai-design-system/source/examples/components-button-togglebutton--size.tsx)

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

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

export const Size = (): JSXElement => {
    const styles = useStyles();
    return (<div className={styles.wrapper}>
      <ToggleButton size="small">Size: small</ToggleButton>
      <ToggleButton size="medium">Size: medium</ToggleButton>
      <ToggleButton size="large">Size: large</ToggleButton>
    </div>);
};

export default Size;
```

## With Long Text

Source: Fluent, adapted for CoreAI.

Text wraps after it hits the max width of the component.

[Download source](/coreai-design-system/source/examples/components-button-togglebutton--with-long-text.tsx)

```tsx
// 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 { ToggleButton } 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}>
      <ToggleButton>Short text</ToggleButton>
      <ToggleButton className={styles.longText}>
        Long text wraps after it hits the max width of the component
      </ToggleButton>
    </div>);
};

export default WithLongText;
```