# Info label

InfoLabel is a combination of a label and info button. When people interact with the info button, the information is surfaced in a Popover.

## Best practices

### Do

- Place critical information in a persistent location where people can easily find it.
- Keep the info button in the page tab order.
- Keep popover content brief and understandable at a glance.

### Don't

- Hide critical information in an info button.
- Use the info button for information required to complete a task.
- Repeat information already shown in visible labels.
- Include more than one link in an info-label popover.

## Behavior and states

- Applying the info button option places an info button next to the label.
- Selecting the info button opens a popover that remains visible until someone selects something else or presses Esc.
- The popover’s placement is determined programmatically to minimize blocking essential information.
- By default, popovers don’t trap focus.
- Because the popover isn’t always visible, don’t include information that people must know in order to complete the field.
- To give people a hint about how to fill in a field, or let them know what values can be entered, try placeholder or helper text instead.

## Default

Source: CoreAI.

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

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

import type { InfoLabelProps } from "@coreai-ds/react-components";
import type { JSXElement } from "@coreai-ds/react-components";
import { InfoLabel } from "@coreai-ds/react-components";
import { Link } from "@coreai-ds/react-components";
import * as React from 'react';

export const Default = (props: Partial<InfoLabelProps>): JSXElement => (<InfoLabel info={<>
        This is example information for an InfoLabel.{' '}
        <Link href="https://react.fluentui.dev">Learn more</Link>
      </>} {...props}>
    Example label
  </InfoLabel>);

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.

### InfoLabel API

InfoLabel component

```ts
interface InfoLabelProps {
  as?: "label";

  children?: any;

  className?: string;

  /**
   * Renders the label as disabled
   * @default false
   */
  disabled?: boolean;

  /**
   * The content of the InfoButton's popover.
   */
  info?: NonNullable<WithSlotShorthandValue<Omit<PopoverSurfaceSlots, "root"> & Omit<{ as?: "div"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & { ref?: ((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null; }, "children"> & { children?: any; }, "ref"> & RefAttributes<HTMLDivElement>> | null> | undefined;

  /**
   * The InfoButton component.
   *
   * It is not typically necessary to use this prop. The content can be set using the `info` prop of the InfoLabel.
   */
  infoButton?: WithSlotShorthandValue<Omit<ComponentProps<Partial<InfoButtonSlots>>, "disabled" | "popover"> & { size?: "small" | "medium" | "large"; inline?: boolean; popover?: NonNullable<WithSlotShorthandValue<Partial<Omit<PopoverProps, "openOnHover">>> | null> | undefined; } & RefAttributes<HTMLButtonElement>> | null | undefined;

  /**
   * The Label component.
   *
   * It is not typically necessary to use this prop. The label text is the child of the `<InfoLabel>`, and other props
   * such as `size` and `required` should be set directly on the `InfoLabel`.
   *
   * This is the PRIMARY slot: all native properties specified directly on `<InfoLabel>` will be applied to this slot,
   * except `className` and `style`, which remain on the root slot.
   */
  label?: NonNullable<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;

  ref?: Ref<HTMLLabelElement>;

  /**
   * Displays an indicator that the label is for a required field. The required prop can be set to true to display
   * an asterisk (*). Or it can be set to a string or jsx content to display a different indicator.
   * @default false
   */
  required?: boolean | WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;

  root?: NonNullable<WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null> | undefined;

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

  style?: CSSProperties;

  /**
   * A label supports regular and semibold fontweight.
   * @default regular
   */
  weight?: "regular" | "semibold";
}
```

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

## In a Field

Source: Fluent, adapted for CoreAI.

An `InfoLabel` can be used in a `Field` by rendering the label prop as an InfoLabel. This uses the slot [render function](https://react.fluentui.dev/?path=/docs/concepts-developer-customizing-components-with-slots--docs#replacing-the-entire-slot) support. See the code from this story for an example.

[Download source](/coreai-design-system/source/examples/components-infolabel--in-field.tsx)

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

export const InField = (): JSXElement => (<Field label={{
        children: (_: unknown, props: LabelProps) => (<InfoLabel {...props} info="Example info">
          Field with info label
        </InfoLabel>),
    }}>
    <Input />
  </Field>);

export default InField;
```

## Required

Source: Fluent, adapted for CoreAI.

When marked `required`, the indicator asterisk is placed before the InfoButton.

[Download source](/coreai-design-system/source/examples/components-infolabel--required.tsx)

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

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

export const Required = (): JSXElement => (<InfoLabel info="Example info" required>
    Required label
  </InfoLabel>);

export default Required;
```

## Size

Source: Fluent, adapted for CoreAI.

InfoLabel's `size` prop affects the size of the Label and InfoButton. The default size is medium. The small size only meets WCAG's minimum target size requirement if it has at least 2px of non-interactive space on all sides.

[Download source](/coreai-design-system/source/examples/components-infolabel--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 { tokens } from "@coreai-ds/react-components";
import { InfoLabel } from "@coreai-ds/react-components";
import * as React from 'react';

const useStyles = makeStyles({
    container: {
        alignItems: 'start',
        display: 'flex',
        flexDirection: 'column',
        rowGap: tokens.spacingVerticalL,
    },
});

export const Size = (): JSXElement => {
    const styles = useStyles();
    return (<div className={styles.container}>
      <InfoLabel size="small" info="Example small InfoLabel">
        Small label
      </InfoLabel>
      <InfoLabel size="medium" info="Example medium InfoLabel">
        Medium label
      </InfoLabel>
      <InfoLabel size="large" info="Example large InfoLabel">
        Large label
      </InfoLabel>
    </div>);
};

export default Size;
```

## Resources

- [Figma component](https://www.figma.com/design/eXfSQrRg3poHRgmr0ivN5V/CoreAI-Figma-Library?node-id=323059-758)
- [Fluent guidance](https://fluent2.microsoft.design/components/web/react/core/infolabel/usage)