# Teaching popover

The Teaching popover component is a versatile tool to help users learn about a new feature.

## Behavior and states

- Teaching popovers live above the UI.
- They can include multi-step learning modules and a section of animation or imagery.
- The component size flexes with its content.
- It lives above the UI and has many optional capabilities such has multi-stepped learning modules and a section of animation or imagery.
- The size of the component flexes with the content to create a contextual learning experience for the user.

## Default

Source: CoreAI.

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

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

import type { JSXElement } from "@coreai-ds/react-components";
import { TeachingPopover } from "@coreai-ds/react-components";
import { TeachingPopoverTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { TeachingPopoverSurface } from "@coreai-ds/react-components";
import { TeachingPopoverHeader } from "@coreai-ds/react-components";
import { TeachingPopoverBody } from "@coreai-ds/react-components";
import { Image } from "@coreai-ds/react-components";
import { TeachingPopoverTitle } from "@coreai-ds/react-components";
import { TeachingPopoverFooter } from "@coreai-ds/react-components";
import * as React from 'react';

const swapImage = 'https://fabricweb.azureedge.net/fabric-website/assets/images/wireframe/image-square.png';

export const Default = (): JSXElement => (<TeachingPopover>
    <TeachingPopoverTrigger>
      <Button>TeachingPopover trigger</Button>
    </TeachingPopoverTrigger>
    <TeachingPopoverSurface>
      <TeachingPopoverHeader>Tips</TeachingPopoverHeader>
      <TeachingPopoverBody media={<Image alt="test image" fit="cover" src={swapImage}/>}>
        <TeachingPopoverTitle>Teaching Bubble Title</TeachingPopoverTitle>
        <div>This is a teaching popover body</div>
      </TeachingPopoverBody>
      <TeachingPopoverFooter primary="Learn more" secondary="Got it"/>
    </TeachingPopoverSurface>
  </TeachingPopover>);

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.

### TeachingPopover API

An extension class of Popover which defaults to withArrow and FocusTrap enabled.

```ts
interface TeachingPopoverProps {
  /**
   * A popover can appear styled with brand or inverted.
   * When not specified, the default style is used.
   */
  appearance?: "brand" | "inverted";

  /**
   * Can contain two children including `PopoverTrigger` and `PopoverSurface`.
   * Alternatively can only contain `PopoverSurface` if using a custom `target`.
   */
  children: JSXElement | [JSXElement, JSXElement];

  /**
   * Flag to close the Popover when an iframe outside a PopoverSurface is focused
   * @default true
   */
  closeOnIframeFocus?: boolean;

  /**
   * Close when scroll outside of it
   * @default false
   */
  closeOnScroll?: boolean;

  /**
   * Used to set the initial open state of the Popover in uncontrolled mode
   * @default false
   */
  defaultOpen?: boolean;

  /**
   * Enables standard behavior according to the [HTML dialog spec](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement/showModal)
   * where the focus trap involves setting outside elements inert,
   * making navigation leak from the trapped area back to the browser toolbar and vice-versa.
   * @default false
   */
  inertTrapFocus?: boolean;

  /**
   * Popovers are rendered out of DOM order on `document.body` by default, use this to render the popover in DOM order
   * @default false
   */
  inline?: boolean;

  /**
   * Must be used with the `trapFocus` prop
   * Enables older Fluent UI focus trap behavior where the user
   * cannot tab into the window outside of the document. This is now
   * non-standard behavior according to the [HTML dialog spec](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement/showModal)
   * where the focus trap involves setting outside elements inert.
   * @deprecated this behavior is default provided now, to opt-out of it in favor of standard behavior use the `inertTrapFocus` property
   */
  legacyTrapFocus?: boolean;

  /**
   * Where the portal children are mounted on DOM
   * @default a new element on document.body without any styling
   */
  mountNode?: HTMLElement | { element?: HTMLElement | null; className?: string; } | null | undefined;

  /**
   * Sets the delay for closing popover on mouse leave
   */
  mouseLeaveDelay?: number;

  /**
   * Call back when the component requests to change value
   * The `open` value is used as a hint when directly controlling the component
   */
  onOpenChange?: ((e: OpenPopoverEvents, data: OnOpenChangeData) => void);

  /**
   * Controls the opening of the Popover
   * @default false
   */
  open?: boolean;

  /**
   * Flag to open the Popover as a context menu. Disables all other interactions
   * @default false
   */
  openOnContext?: boolean;

  /**
   * Flag to open the Popover by hovering the trigger
   * @default false
   */
  openOnHover?: boolean;

  /**
   * Configures the position of the Popover.
   * Explore [Positioning docs](https://react.fluentui.dev/?path=/docs/concepts-developer-positioning-components--docs) for more options.
   */
  positioning?: PositioningShorthand;

  /**
   * Determines popover padding and arrow size
   * @default medium
   */
  size?: "small" | "medium" | "large";

  /**
   * Slot for the surface motion animation.
   * For more information refer to the [Motion docs page](https://react.fluentui.dev/?path=/docs/motion-motion-slot--docs).
   */
  surfaceMotion?: PresenceMotionSlotProps | null;

  /**
   * Should trap focus
   * @default false
   */
  trapFocus?: boolean;

  /**
   * By default Popover focuses the first focusable element in PopoverSurface on open.
   * Specify `disableAutoFocus` to prevent this behavior.
   * @default false
   */
  unstable_disableAutoFocus?: boolean;

  /**
   * Display an arrow pointing to the target.
   * @default false
   */
  withArrow?: boolean;
}
```

### TeachingPopoverBody API

Define a styled TeachingPopoverBody, using the `useTeachingPopoverBody_unstable` and `useTeachingPopoverBodyStyles_unstable`
hooks.

TeachingPopoverBody is used to host content within a TeachingPopover, and provides a standardized media slot

```ts
interface TeachingPopoverBodyProps {
  as?: "div";

  children?: any;

  className?: string;

  /**
   * Optional Media Content.
   */
  media?: WithSlotShorthandValue<{ as?: "span"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & { ref?: ((instance: HTMLSpanElement | null) => void) | RefObject<HTMLSpanElement> | null; }, "children"> & { children?: any; }> | null | undefined;

  mediaLength?: "medium" | "short" | "tall";

  ref?: Ref<HTMLDivElement>;

  style?: CSSProperties;
}
```

### TeachingPopoverCarousel API

Define a styled TeachingPopoverCarousel, using the `useTeachingPopoverCarousel_unstable` and `useTeachingPopoverCarouselStyles_unstable`
hooks.

TeachingPopoverCarousel injects context providers that are required for TeachingPopoverCarouselCard display and navigation functionality

```ts
interface TeachingPopoverCarouselProps {
  /**
   * Localizes the string used to announce carousel page changes to screen reader users
   * Defaults to: undefined
   */
  announcement?: ((newValue: string) => string);

  as?: "div";

  children?: any;

  className?: string;

  /**
   * The initial page to display in uncontrolled mode.
   */
  defaultValue?: string | number | readonly string[];

  /**
   * Callback to notify when the final button step of a carousel has been activated.
   */
  onFinish?: EventHandler<CarouselValueChangeData>;

  /**
   * Callback to notify a page change.
   */
  onValueChange?: EventHandler<CarouselValueChangeData>;

  ref?: Ref<HTMLDivElement>;

  style?: CSSProperties;

  /**
   * The value of the currently active page.
   */
  value?: string;
}
```

### TeachingPopoverCarouselCard API

Define a styled TeachingPopoverCarouselCard, using the `useTeachingPopoverCarouselCard_unstable` and `useTeachingPopoverCarouselCardStyles_unstable`
hooks.

TeachingPopoverCarouselCard is the definition of a single page view within the carousel, they are shown one at a time and can be navigated through sequentially.

```ts
interface TeachingPopoverCarouselCardProps {
  as?: "div";

  children?: any;

  className?: string;

  ref?: Ref<HTMLDivElement>;

  style?: CSSProperties;

  /**
   * The value used to identify a page,
   * it should be unique and is necessary for pagination
   */
  value: string;
}
```

### TeachingPopoverCarouselFooter API

Define a styled TeachingPopoverCarouselFooter, using the `useTeachingPopoverCarouselFooter_unstable` and `useTeachingPopoverCarouselFooterStyles_unstable`
hooks.

TeachingPopoverCarouselFooter contains previous/next buttons configured for carousel navigation, and a root slot for page count and/or page index navigation.

```ts
interface TeachingPopoverCarouselFooterProps {
  as?: "div";

  children?: any;

  className?: string;

  /**
   * The text to be displayed on the final step of carousel
   */
  finalStepText: string;

  /**
   * The text to be displayed on the initial step of carousel
   */
  initialStepText: string;

  /**
   * Controls whether buttons will be centered (balanced) or right aligned
   * Defaults to 'centered'.
   */
  layout?: "offset" | "centered";

  /**
   * The next button slot.
   */
  next: NonNullable<WithSlotShorthandValue<(Omit<TeachingPopoverCarouselFooterButtonSlots, "root"> & Omit<{ as?: "button" | undefined; } & Omit<Omit<DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & { ref?: ((instance: HTMLButtonElement | null) => void) | RefObject<HTMLButtonElement> | null | undefined; }, "children"> & { children?: any; } & Pick<ARIAButtonProps<ARIAButtonType>, "disabled" | "disabledFocusable">, "ref"> & Omit<ButtonSlots, "root"> & { appearance?: "outline" | "subtle" | "secondary" | "primary" | "transparent" | undefined; disabledFocusable?: boolean | undefined; disabled?: boolean | undefined; iconPosition?: "before" | "after" | undefined; shape?: "circular" | "rounded" | "square" | undefined; size?: ButtonSize | undefined; } & { navType: "next" | "prev"; altText: ReactNode; }) | (Omit<TeachingPopoverCarouselFooterButtonSlots, "root"> & Omit<{ as: "a"; } & Omit<Omit<DetailedHTMLProps<AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>, "ref"> & { ref?: ((instance: HTMLAnchorElement | null) => void) | RefObject<HTMLAnchorElement> | null | undefined; }, "children"> & { children?: any; } & Pick<ARIAButtonProps<ARIAButtonType>, "disabled" | "disabledFocusable">, "ref"> & Omit<ButtonSlots, "root"> & { appearance?: "outline" | "subtle" | "secondary" | "primary" | "transparent" | undefined; disabledFocusable?: boolean | undefined; disabled?: boolean | undefined; iconPosition?: "before" | "after" | undefined; shape?: "circular" | "rounded" | "square" | undefined; size?: ButtonSize | undefined; } & { navType: "next" | "prev"; altText: ReactNode; })> | null>;

  /**
   * The previous button slot.
   */
  previous?: WithSlotShorthandValue<(Omit<TeachingPopoverCarouselFooterButtonSlots, "root"> & Omit<{ as?: "button"; } & Omit<Omit<DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & { ref?: ((instance: HTMLButtonElement | null) => void) | RefObject<HTMLButtonElement> | null; }, "children"> & { children?: any; } & Pick<ARIAButtonProps<ARIAButtonType>, "disabled" | "disabledFocusable">, "ref"> & Omit<ButtonSlots, "root"> & { appearance?: "outline" | "subtle" | "secondary" | "primary" | "transparent" | undefined; disabledFocusable?: boolean | undefined; disabled?: boolean | undefined; iconPosition?: "before" | "after" | undefined; shape?: "circular" | "rounded" | "square" | undefined; size?: ButtonSize | undefined; } & { navType: "next" | "prev"; altText: ReactNode; }) | (Omit<TeachingPopoverCarouselFooterButtonSlots, "root"> & Omit<{ as: "a"; } & Omit<Omit<DetailedHTMLProps<AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>, "ref"> & { ref?: ((instance: HTMLAnchorElement | null) => void) | RefObject<HTMLAnchorElement> | null | undefined; }, "children"> & { children?: any; } & Pick<ARIAButtonProps<ARIAButtonType>, "disabled" | "disabledFocusable">, "ref"> & Omit<ButtonSlots, "root"> & { appearance?: "outline" | "subtle" | "secondary" | "primary" | "transparent" | undefined; disabledFocusable?: boolean | undefined; disabled?: boolean | undefined; iconPosition?: "before" | "after" | undefined; shape?: "circular" | "rounded" | "square" | undefined; size?: ButtonSize | undefined; } & { navType: "next" | "prev"; altText: ReactNode; })> | null | undefined;

  ref?: Ref<HTMLDivElement>;

  style?: CSSProperties;
}
```

### TeachingPopoverCarouselNav API

Define a styled TeachingPopoverCarouselNav, using the `useTeachingPopoverCarouselNav_unstable` and `useTeachingPopoverCarouselNavStyles_unstable`
hooks.

TeachingPopoverCarouselNav provides an index-based pagination list to jump to any page within the carousel.

```ts
interface TeachingPopoverCarouselNavProps {
  as?: "div";

  children: NavButtonRenderFunction;

  className?: string;

  ref?: Ref<HTMLDivElement>;

  style?: CSSProperties;
}
```

### TeachingPopoverCarouselNavButton API

TeachingPopoverCarouselNavButton is a button to jump to a single page within TeachingPopoverCarousel

It's value is injected via context and must be wrapped with a ValueIdContextProvider (automatically handled via TeachingPopoverCarouselNav)

```ts
interface TeachingPopoverCarouselNavButtonProps {
  as?: "a" | "button";

  children?: any;

  className?: string;

  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.
   * @default false
   */
  disabledFocusable?: boolean;

  ref?: Ref<HTMLAnchorElement | HTMLButtonElement>;

  style?: CSSProperties;
}
```

### TeachingPopoverCarouselPageCount API

TeachingPopoverCarouselPageCount is a simple interface for rendering based on current and total page count

The child render function will provide both current and total page numbers for customization.

```ts
interface TeachingPopoverCarouselPageCountProps {
  as?: "div";

  children: TeachingPopoverCarouselPageCountRenderFunction;

  className?: string;

  ref?: Ref<HTMLDivElement>;

  style?: CSSProperties;
}
```

### TeachingPopoverFooter API

Define a styled TeachingPopoverFooter, using the `useTeachingPopoverFooter_unstable` and `useTeachingPopoverFooterStyles_unstable`
hooks.

TeachingPopoverFooter will provide both a secondary and primary button for the TeachingPopover,
and handle Popover functionality such as closing the popup.

Users must provide the localized text for each button within the footer via slots.

```ts
interface TeachingPopoverFooterProps {
  as?: "div";

  children?: any;

  className?: string;

  /**
   * Enables stylization to a horizontal or vertical stack of button layouts.
   * Defaults to horizontal
   */
  footerLayout?: "horizontal" | "vertical";

  /**
   * The primary button slot.
   */
  primary: NonNullable<WithSlotShorthandValue<ButtonProps & RefAttributes<HTMLAnchorElement | HTMLButtonElement>> | null>;

  ref?: Ref<HTMLDivElement>;

  /**
   * The secondary button slot.
   */
  secondary?: WithSlotShorthandValue<ButtonProps & RefAttributes<HTMLAnchorElement | HTMLButtonElement>> | null;

  style?: CSSProperties;
}
```

### TeachingPopoverHeader API

Define a styled TeachingPopoverHeader, using the `useTeachingPopoverHeader_unstable` and `useTeachingPopoverHeaderStyles_unstable`
hooks.

TeachingPopoverHeader is an info subtitle located at the top of the popover, it provides a dismiss button by default (can be nulled)
and an info-tip icon that can be overridden or removed, subtitle displayed will be the children elements of TeachingPopoverHeader.

```ts
interface TeachingPopoverHeaderProps {
  as?: "div" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6";

  children?: any;

  className?: string;

  /**
   * The component to be used as close button in heading
   */
  dismissButton?: WithSlotShorthandValue<{ as?: "button"; } & Omit<Omit<DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & { ref?: ((instance: HTMLButtonElement | null) => void) | RefObject<HTMLButtonElement> | null; }, "children"> & { children?: any; }> | null | undefined;

  /**
   * Initial icon slot rendered before children content in heading.
   */
  icon?: WithSlotShorthandValue<{ as?: "div"; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & { ref?: ((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null; }, "children"> & { children?: any; }> | null | undefined;

  ref?: Ref<HTMLDivElement>;

  style?: CSSProperties;
}
```

### TeachingPopoverSurface API

TeachingPopoverSurface component renders react children in a positioned box

TeachingPopoverSurface is a direct extension of PopoverSurface, with it's own styling context hooks available.

```ts
interface TeachingPopoverSurfaceProps {
  as?: "div";

  children?: any;

  className?: string;

  ref?: Ref<HTMLDivElement>;

  style?: CSSProperties;
}
```

### TeachingPopoverTitle API

Define a styled TeachingPopoverTitle, using the `useTeachingPopoverTitle_unstable` and `useTeachingPopoverTitleStyles_unstable`
hooks.

TeachingPopoverTitle is similar to TeachingPopoverHeader, but it is intended to be placed within a TeachingPopoverBody
TeachingPopoverTitle can also optionally render a dismiss button, however this should only be enabled when there is no TeachingPopoverHeader/dismiss.

```ts
interface TeachingPopoverTitleProps {
  as?: "div" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6";

  children?: any;

  className?: string;

  /**
   * An alternate close button path if not placed in the TeachingPopoverHeader
   */
  dismissButton?: WithSlotShorthandValue<{ as?: "button"; } & Omit<Omit<DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & { ref?: ((instance: HTMLButtonElement | null) => void) | RefObject<HTMLButtonElement> | null; }, "children"> & { children?: any; }> | null | undefined;

  ref?: Ref<HTMLDivElement>;

  style?: CSSProperties;
}
```

### TeachingPopoverTrigger API

Direct extension of PopoverTrigger - Wraps a trigger element as an only child and adds the necessary event handling to open a teaching bubble.

```ts
interface TeachingPopoverTriggerProps {
  children?: ReactElement<any, string | JSXElementConstructor<any>> | ((props: PopoverTriggerChildProps<ARIAButtonType, {}>) => ReactElement<any, string | JSXElementConstructor<any>> | null) | null;

  /**
   * Disables internal trigger mechanism that ensures a child provided will be a compliant ARIA button.
   * @default false
   */
  disableButtonEnhancement?: boolean;
}
```

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

## Appearance Brand

Source: Fluent, adapted for CoreAI.

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

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

import type { JSXElement } from "@coreai-ds/react-components";
import { TeachingPopover } from "@coreai-ds/react-components";
import { TeachingPopoverTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { TeachingPopoverSurface } from "@coreai-ds/react-components";
import { TeachingPopoverHeader } from "@coreai-ds/react-components";
import { TeachingPopoverBody } from "@coreai-ds/react-components";
import { Image } from "@coreai-ds/react-components";
import { TeachingPopoverTitle } from "@coreai-ds/react-components";
import { TeachingPopoverFooter } from "@coreai-ds/react-components";
import * as React from 'react';

const swapImage = 'https://fabricweb.azureedge.net/fabric-website/assets/images/wireframe/image-square.png';

export const AppearanceBrand = (): JSXElement => (<TeachingPopover appearance="brand">
    <TeachingPopoverTrigger>
      <Button>TeachingPopover trigger</Button>
    </TeachingPopoverTrigger>
    <TeachingPopoverSurface>
      <TeachingPopoverHeader>Tips</TeachingPopoverHeader>
      <TeachingPopoverBody media={<Image alt="test image" fit="cover" src={swapImage}/>}>
        <TeachingPopoverTitle>Teaching Bubble Title</TeachingPopoverTitle>
        <div>This is a teaching popover body</div>
      </TeachingPopoverBody>
      <TeachingPopoverFooter primary="Learn more" secondary="Got it"/>
    </TeachingPopoverSurface>
  </TeachingPopover>);

export default AppearanceBrand;
```

## Carousel

Source: Fluent, adapted for CoreAI.

[Download source](/coreai-design-system/source/examples/components-teachingpopover--carousel.tsx)

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

import type { JSXElement } from "@coreai-ds/react-components";
import { TeachingPopover } from "@coreai-ds/react-components";
import { TeachingPopoverTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { TeachingPopoverSurface } from "@coreai-ds/react-components";
import { TeachingPopoverHeader } from "@coreai-ds/react-components";
import { TeachingPopoverCarousel } from "@coreai-ds/react-components";
import { TeachingPopoverCarouselCard } from "@coreai-ds/react-components";
import { TeachingPopoverBody } from "@coreai-ds/react-components";
import { Image } from "@coreai-ds/react-components";
import { TeachingPopoverTitle } from "@coreai-ds/react-components";
import { TeachingPopoverCarouselFooter } from "@coreai-ds/react-components";
import { TeachingPopoverCarouselNav } from "@coreai-ds/react-components";
import { TeachingPopoverCarouselNavButton } from "@coreai-ds/react-components";
import * as React from 'react';

const getAnnouncement = (newValue: string) => {
    return `Carousel slide ${newValue}`;
};

const swapImage = 'https://fabricweb.azureedge.net/fabric-website/assets/images/wireframe/image-square.png';

export const Carousel = (): JSXElement => (<TeachingPopover>
    <TeachingPopoverTrigger>
      <Button>TeachingPopover trigger</Button>
    </TeachingPopoverTrigger>
    <TeachingPopoverSurface>
      <TeachingPopoverHeader>Tips</TeachingPopoverHeader>
      <TeachingPopoverCarousel defaultValue={'1'} announcement={getAnnouncement}>
        <TeachingPopoverCarouselCard value="1">
          <TeachingPopoverBody media={<Image alt="test image" fit="cover" src={swapImage}/>}>
            <TeachingPopoverTitle>Teaching Bubble Title</TeachingPopoverTitle>
            <div>This is page: 1</div>
          </TeachingPopoverBody>
        </TeachingPopoverCarouselCard>

        <TeachingPopoverCarouselCard value="2">
          <TeachingPopoverBody media={<Image alt="test image" fit="cover" src={swapImage}/>}>
            <TeachingPopoverTitle>Teaching Bubble Title</TeachingPopoverTitle>
            <div>This is page: 2</div>
          </TeachingPopoverBody>
        </TeachingPopoverCarouselCard>

        <TeachingPopoverCarouselCard value="3">
          <TeachingPopoverBody media={<Image alt="test image" fit="cover" src={swapImage}/>}>
            <TeachingPopoverTitle>Teaching Bubble Title</TeachingPopoverTitle>
            <div>This is page: 3</div>
          </TeachingPopoverBody>
        </TeachingPopoverCarouselCard>

        <TeachingPopoverCarouselFooter next="Next" previous="Previous" initialStepText="Close" finalStepText="Finish">
          <TeachingPopoverCarouselNav>
            {index => <TeachingPopoverCarouselNavButton aria-label={`Tip ${index}`}/>}
          </TeachingPopoverCarouselNav>
        </TeachingPopoverCarouselFooter>
      </TeachingPopoverCarousel>
    </TeachingPopoverSurface>
  </TeachingPopover>);

export default Carousel;
```

## Carousel Brand

Source: Fluent, adapted for CoreAI.

[Download source](/coreai-design-system/source/examples/components-teachingpopover--carousel-brand.tsx)

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

import type { JSXElement } from "@coreai-ds/react-components";
import { TeachingPopover } from "@coreai-ds/react-components";
import { TeachingPopoverTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { TeachingPopoverSurface } from "@coreai-ds/react-components";
import { TeachingPopoverHeader } from "@coreai-ds/react-components";
import { TeachingPopoverCarousel } from "@coreai-ds/react-components";
import { TeachingPopoverCarouselCard } from "@coreai-ds/react-components";
import { TeachingPopoverBody } from "@coreai-ds/react-components";
import { Image } from "@coreai-ds/react-components";
import { TeachingPopoverTitle } from "@coreai-ds/react-components";
import { TeachingPopoverCarouselFooter } from "@coreai-ds/react-components";
import { TeachingPopoverCarouselNav } from "@coreai-ds/react-components";
import { TeachingPopoverCarouselNavButton } from "@coreai-ds/react-components";
import * as React from 'react';

const swapImage = 'https://fabricweb.azureedge.net/fabric-website/assets/images/wireframe/image-square.png';

export const CarouselBrand = (): JSXElement => (<TeachingPopover appearance="brand">
    <TeachingPopoverTrigger>
      <Button>TeachingPopover trigger</Button>
    </TeachingPopoverTrigger>
    <TeachingPopoverSurface>
      <TeachingPopoverHeader>Tips</TeachingPopoverHeader>
      <TeachingPopoverCarousel defaultValue="1">
        <TeachingPopoverCarouselCard value="1">
          <TeachingPopoverBody media={<Image alt="test image" fit="cover" src={swapImage}/>}>
            <TeachingPopoverTitle>Teaching Bubble Title</TeachingPopoverTitle>
            <div>This is page: 1</div>
          </TeachingPopoverBody>
        </TeachingPopoverCarouselCard>

        <TeachingPopoverCarouselCard value="2">
          <TeachingPopoverBody media={<Image alt="test image" fit="cover" src={swapImage}/>}>
            <TeachingPopoverTitle>Teaching Bubble Title</TeachingPopoverTitle>
            <div>This is page: 2</div>
          </TeachingPopoverBody>
        </TeachingPopoverCarouselCard>

        <TeachingPopoverCarouselCard value="3">
          <TeachingPopoverBody media={<Image alt="test image" fit="cover" src={swapImage}/>}>
            <TeachingPopoverTitle>Teaching Bubble Title</TeachingPopoverTitle>
            <div>This is page: 3</div>
          </TeachingPopoverBody>
        </TeachingPopoverCarouselCard>

        <TeachingPopoverCarouselFooter next="Next" previous="Previous" initialStepText="Close" finalStepText="Finish">
          <TeachingPopoverCarouselNav>
            {index => <TeachingPopoverCarouselNavButton aria-label={`Tip ${index}`}/>}
          </TeachingPopoverCarouselNav>
        </TeachingPopoverCarouselFooter>
      </TeachingPopoverCarousel>
    </TeachingPopoverSurface>
  </TeachingPopover>);

export default CarouselBrand;
```

## Carousel Text

Source: Fluent, adapted for CoreAI.

[Download source](/coreai-design-system/source/examples/components-teachingpopover--carousel-text.tsx)

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

import type { JSXElement } from "@coreai-ds/react-components";
import { TeachingPopover } from "@coreai-ds/react-components";
import { TeachingPopoverTrigger } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { TeachingPopoverSurface } from "@coreai-ds/react-components";
import { TeachingPopoverHeader } from "@coreai-ds/react-components";
import { TeachingPopoverCarousel } from "@coreai-ds/react-components";
import { TeachingPopoverCarouselCard } from "@coreai-ds/react-components";
import { TeachingPopoverBody } from "@coreai-ds/react-components";
import { Image } from "@coreai-ds/react-components";
import { TeachingPopoverTitle } from "@coreai-ds/react-components";
import { TeachingPopoverCarouselFooter } from "@coreai-ds/react-components";
import { TeachingPopoverCarouselPageCount } from "@coreai-ds/react-components";
import * as React from 'react';

const swapImage = 'https://fabricweb.azureedge.net/fabric-website/assets/images/wireframe/image-square.png';

export const CarouselText = (): JSXElement => (<TeachingPopover>
    <TeachingPopoverTrigger>
      <Button>TeachingPopover trigger</Button>
    </TeachingPopoverTrigger>
    <TeachingPopoverSurface>
      <TeachingPopoverHeader>Tips"</TeachingPopoverHeader>
      <TeachingPopoverCarousel defaultValue="1">
        <TeachingPopoverCarouselCard value="1">
          <TeachingPopoverBody media={<Image alt="test image" fit="cover" src={swapImage}/>}>
            <TeachingPopoverTitle>Teaching Bubble Title</TeachingPopoverTitle>
            <div>This is page: 1</div>
          </TeachingPopoverBody>
        </TeachingPopoverCarouselCard>

        <TeachingPopoverCarouselCard value="2">
          <TeachingPopoverBody media={<Image alt="test image" fit="cover" src={swapImage}/>}>
            <TeachingPopoverTitle>Teaching Bubble Title</TeachingPopoverTitle>
            <div>This is page: 2</div>
          </TeachingPopoverBody>
        </TeachingPopoverCarouselCard>

        <TeachingPopoverCarouselCard value="3">
          <TeachingPopoverBody media={<Image alt="test image" fit="cover" src={swapImage}/>}>
            <TeachingPopoverTitle>Teaching Bubble Title</TeachingPopoverTitle>
            <div>This is page: 3</div>
          </TeachingPopoverBody>
        </TeachingPopoverCarouselCard>

        <TeachingPopoverCarouselFooter next="Next" previous="Previous" initialStepText="Close" finalStepText="Finish">
          <TeachingPopoverCarouselPageCount>
            {(currentIndex: number, totalPages: number) => `${currentIndex} of ${totalPages}`}
          </TeachingPopoverCarouselPageCount>
        </TeachingPopoverCarouselFooter>
      </TeachingPopoverCarousel>
    </TeachingPopoverSurface>
  </TeachingPopover>);

export default CarouselText;
```

## Resources

- [Figma component](https://www.figma.com/design/eXfSQrRg3poHRgmr0ivN5V/CoreAI-Figma-Library?node-id=170592-76650)