or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

buttons.mddata-display.mdforms.mdindex.mdlayout.mdnavigation.mdoverlays.mdpickers.mdstyling-theming.mdutilities.md
tile.json

overlays.mddocs/

Overlay Components

Modal overlays, dialogs, callouts, and tooltips for secondary content and user interactions. These components provide layered UI elements that appear above the main content.

Capabilities

Modal

Modal dialog overlay that blocks interaction with the underlying page.

/**
 * Modal dialog overlay component
 * @param props - Modal properties
 * @returns JSX element for modal
 */
function Modal(props: IModalProps): JSX.Element;

interface IModalProps {
  /** Whether modal is open */
  isOpen?: boolean;
  /** Whether modal is blocking (prevents closing by clicking outside) */
  isBlocking?: boolean;
  /** Whether to show dark overlay */
  isDarkOverlay?: boolean;
  /** Dismiss handler */
  onDismiss?: (event?: React.MouseEvent<HTMLButtonElement>) => void;
  /** Layer props for portal rendering */
  layerProps?: ILayerProps;
  /** Drag options for draggable modal */
  dragOptions?: IDragOptions;
  /** Whether modal is modeless */
  isModeless?: boolean;
  /** Container class name */
  containerClassName?: string;
  /** Scroll bar visibility */
  scrollableContentClassName?: string;
  /** Custom styles */
  styles?: IModalStyles;
  /** Theme */
  theme?: ITheme;
}

interface IDragOptions {
  /** Move menu on drag */
  moveMenuOnDrag?: boolean;
  /** Keep in bounds */
  keepInBounds?: boolean;
  /** Drag handle selector */
  dragHandleSelector?: string;
}

Usage Examples:

import React, { useState } from "react";
import { Modal, PrimaryButton, DefaultButton, Stack } from "@fluentui/react";

function ModalExample() {
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [isBlockingModal, setIsBlockingModal] = useState(false);

  return (
    <>
      <PrimaryButton 
        text="Open Modal" 
        onClick={() => setIsModalOpen(true)} 
      />
      
      <Modal
        isOpen={isModalOpen}
        onDismiss={() => setIsModalOpen(false)}
        isBlocking={isBlockingModal}
        containerClassName="modal-container"
      >
        <div style={{ padding: '20px', minWidth: '400px' }}>
          <h2>Modal Dialog</h2>
          <p>This is modal content. Click outside to close (unless blocking).</p>
          
          <Stack horizontal tokens={{ childrenGap: 10 }}>
            <PrimaryButton 
              text="Save" 
              onClick={() => {
                console.log('Saved');
                setIsModalOpen(false);
              }} 
            />
            <DefaultButton 
              text="Cancel" 
              onClick={() => setIsModalOpen(false)} 
            />
          </Stack>
          
          <div style={{ marginTop: '20px' }}>
            <input
              type="checkbox"
              checked={isBlockingModal}
              onChange={(e) => setIsBlockingModal(e.target.checked)}
            />
            <label>Blocking modal</label>
          </div>
        </div>
      </Modal>
    </>
  );
}

Panel

Slide-out panel that appears from the side of the screen.

/**
 * Slide-out panel component
 * @param props - Panel properties
 * @returns JSX element for panel
 */
function Panel(props: IPanelProps): JSX.Element;

interface IPanelProps {
  /** Whether panel is open */
  isOpen?: boolean;
  /** Panel type (size and position) */
  type?: PanelType;
  /** Whether panel is light dismiss */
  isLightDismiss?: boolean;
  /** Whether panel is blocking */
  isBlocking?: boolean;
  /** Dismiss handler */
  onDismiss?: (event?: React.SyntheticEvent<HTMLElement>) => void;
  /** Whether to show close button */
  hasCloseButton?: boolean;
  /** Close button ARIA label */
  closeButtonAriaLabel?: string;
  /** Panel header text */
  headerText?: string;
  /** Custom header renderer */
  onRenderHeader?: IPanelHeaderRenderer;
  /** Custom navigation renderer */
  onRenderNavigation?: (props?: IPanelProps, defaultRender?: IPanelHeaderRenderer) => JSX.Element | null;
  /** Custom footer renderer */
  onRenderFooter?: (props?: IPanelProps, defaultRender?: () => JSX.Element | null) => JSX.Element | null;
  /** Custom styles */
  styles?: IPanelStyles;
}

enum PanelType {
  smallFluid = 0,
  smallFixedFar = 1,
  smallFixedNear = 2,
  medium = 3,
  large = 4,
  largeFixed = 5,
  extraLarge = 6,
  custom = 7,
  customNear = 8,
}

type IPanelHeaderRenderer = (
  props?: IPanelProps,
  defaultRender?: (props?: IPanelProps) => JSX.Element | null,
  headerTextId?: string
) => JSX.Element | null;

Usage Examples:

import React, { useState } from "react";
import { Panel, PanelType, PrimaryButton, Stack, TextField } from "@fluentui/react";

function PanelExample() {
  const [isPanelOpen, setIsPanelOpen] = useState(false);
  const [panelType, setPanelType] = useState(PanelType.medium);

  return (
    <>
      <PrimaryButton 
        text="Open Panel" 
        onClick={() => setIsPanelOpen(true)} 
      />
      
      <Panel
        isOpen={isPanelOpen}
        type={panelType}
        onDismiss={() => setIsPanelOpen(false)}
        headerText="Panel Example"
        closeButtonAriaLabel="Close panel"
        onRenderFooter={() => (
          <Stack horizontal tokens={{ childrenGap: 10 }}>
            <PrimaryButton 
              text="Save" 
              onClick={() => {
                console.log('Panel saved');
                setIsPanelOpen(false);
              }} 
            />
            <DefaultButton 
              text="Cancel" 
              onClick={() => setIsPanelOpen(false)} 
            />
          </Stack>
        )}
      >
        <div>
          <TextField label="Name" placeholder="Enter your name" />
          <TextField label="Email" placeholder="Enter your email" />
          <TextField 
            label="Comments" 
            multiline 
            rows={4} 
            placeholder="Enter comments" 
          />
        </div>
      </Panel>
    </>
  );
}

Dialog

Structured dialog component with header, content, and footer sections.

/**
 * Structured dialog component
 * @param props - Dialog properties
 * @returns JSX element for dialog
 */
function Dialog(props: IDialogProps): JSX.Element;

/**
 * Dialog content container
 * @param props - Dialog content properties
 * @returns JSX element for dialog content
 */
function DialogContent(props: IDialogContentProps): JSX.Element;

/**
 * Dialog footer container
 * @param props - Dialog footer properties
 * @returns JSX element for dialog footer
 */
function DialogFooter(props: IDialogFooterProps): JSX.Element;

interface IDialogProps {
  /** Whether dialog is hidden */
  hidden?: boolean;
  /** Dialog type */
  type?: DialogType;
  /** Dismiss handler */
  onDismiss?: (event?: React.MouseEvent<HTMLButtonElement>) => void;
  /** Title for dialog */
  title?: string;
  /** Subtitle for dialog */
  subText?: string;
  /** Whether dialog is blocking */
  isBlocking?: boolean;
  /** Whether dialog is draggable */
  isDraggable?: boolean;
  /** Modal properties */
  modalProps?: IModalProps;
  /** Custom styles */
  styles?: IDialogStyles;
}

interface IDialogContentProps {
  /** Title text */
  title?: string;
  /** Subtitle text */
  subText?: string;
  /** Show close button */
  showCloseButton?: boolean;
  /** Close button ARIA label */
  closeButtonAriaLabel?: string;
  /** Title ID for ARIA */
  titleId?: string;
  /** Subtitle ID for ARIA */
  subTextId?: string;
  /** Custom styles */
  styles?: IDialogContentStyles;
}

interface IDialogFooterProps {
  /** Custom styles */
  styles?: IDialogFooterStyles;
}

enum DialogType {
  normal = 0,
  largeHeader = 1,
  close = 2,
}

Usage Examples:

import React, { useState } from "react";
import { 
  Dialog, 
  DialogContent, 
  DialogFooter, 
  DialogType,
  PrimaryButton, 
  DefaultButton 
} from "@fluentui/react";

function DialogExample() {
  const [isDialogVisible, setIsDialogVisible] = useState(false);

  return (
    <>
      <PrimaryButton 
        text="Show Dialog" 
        onClick={() => setIsDialogVisible(true)} 
      />
      
      <Dialog
        hidden={!isDialogVisible}
        onDismiss={() => setIsDialogVisible(false)}
        type={DialogType.normal}
        isBlocking={false}
      >
        <DialogContent
          title="Confirm Action"
          subText="Are you sure you want to delete this item? This action cannot be undone."
          showCloseButton={true}
          closeButtonAriaLabel="Close dialog"
        />
        <DialogFooter>
          <PrimaryButton 
            text="Delete" 
            onClick={() => {
              console.log('Item deleted');
              setIsDialogVisible(false);
            }} 
          />
          <DefaultButton 
            text="Cancel" 
            onClick={() => setIsDialogVisible(false)} 
          />
        </DialogFooter>
      </Dialog>
    </>
  );
}

Callout

Positioned callout/popover component that points to a target element.

/**
 * Positioned callout/popover component
 * @param props - Callout properties
 * @returns JSX element for callout
 */
function Callout(props: ICalloutProps): JSX.Element;

/**
 * Callout content container
 * @param props - Callout content properties
 * @returns JSX element for callout content
 */
function CalloutContent(props: ICalloutContentStyleProps): JSX.Element;

/**
 * Focus trap callout with focus management
 * @param props - Focus trap callout properties
 * @returns JSX element for focus trap callout
 */
function FocusTrapCallout(props: IFocusTrapCalloutProps): JSX.Element;

interface ICalloutProps {
  /** Target element or coordinates */
  target?: Element | string | MouseEvent | Point | React.RefObject<Element>;
  /** Directional hint for positioning */
  directionalHint?: DirectionalHint;
  /** Gap space between callout and target */
  gapSpace?: number;
  /** Beak width */
  beakWidth?: number;
  /** Whether callout is visible */
  hidden?: boolean;
  /** Dismiss handler */
  onDismiss?: (event?: any) => void;
  /** Position change handler */
  onPositioned?: (positions?: ICalloutPositionedInfo) => void;
  /** Whether to set initial focus */
  setInitialFocus?: boolean;
  /** Cover target */
  coverTarget?: boolean;
  /** Role for accessibility */
  role?: string;
  /** ARIA label */
  ariaLabel?: string;
  /** Custom styles */
  styles?: any;
}

interface IFocusTrapCalloutProps extends ICalloutProps {
  /** Focus trap zone properties */
  focusTrapProps?: IFocusTrapZoneProps;
}

Usage Examples:

import React, { useState, useRef } from "react";
import { 
  Callout, 
  DirectionalHint, 
  PrimaryButton, 
  DefaultButton,
  Text,
  Stack
} from "@fluentui/react";

function CalloutExample() {
  const [isCalloutVisible, setIsCalloutVisible] = useState(false);
  const buttonRef = useRef<HTMLButtonElement>(null);

  return (
    <>
      <PrimaryButton 
        ref={buttonRef}
        text="Show Callout" 
        onClick={() => setIsCalloutVisible(!isCalloutVisible)} 
      />
      
      {isCalloutVisible && (
        <Callout
          target={buttonRef}
          directionalHint={DirectionalHint.bottomLeftEdge}
          onDismiss={() => setIsCalloutVisible(false)}
          setInitialFocus={true}
          role="dialog"
          ariaLabel="Callout with information"
        >
          <div style={{ padding: '20px', maxWidth: '300px' }}>
            <Text variant="medium" block>
              This is a callout with some information. It points to the button that opened it.
            </Text>
            <Stack horizontal tokens={{ childrenGap: 10 }} style={{ marginTop: '15px' }}>
              <PrimaryButton 
                text="OK" 
                onClick={() => setIsCalloutVisible(false)} 
              />
              <DefaultButton 
                text="Cancel" 
                onClick={() => setIsCalloutVisible(false)} 
              />
            </Stack>
          </div>
        </Callout>
      )}
    </>
  );
}

Tooltip

Simple tooltip component for providing additional information on hover.

/**
 * Simple tooltip component
 * @param props - Tooltip properties
 * @returns JSX element for tooltip
 */
function Tooltip(props: ITooltipProps): JSX.Element;

/**
 * Tooltip host component that manages tooltip display
 * @param props - Tooltip host properties
 * @returns JSX element for tooltip host
 */
function TooltipHost(props: ITooltipHostProps): JSX.Element;

interface ITooltipProps {
  /** Tooltip content */
  content?: string | JSX.Element;
  /** Target element */
  targetElement?: HTMLElement;
  /** Directional hint */
  directionalHint?: DirectionalHint;
  /** Gap space */
  gapSpace?: number;
  /** Maximum width */
  maxWidth?: string;
  /** Delay before showing */
  delay?: TooltipDelay;
  /** Custom styles */
  styles?: ITooltipStyles;
}

interface ITooltipHostProps {
  /** Tooltip content */
  content?: string | JSX.Element;
  /** Directional hint */
  directionalHint?: DirectionalHint;
  /** Delay before showing */
  delay?: TooltipDelay;
  /** Overflow mode */
  overflowMode?: TooltipOverflowMode;
  /** Call out properties */
  calloutProps?: ICalloutProps;
  /** Custom styles */
  styles?: ITooltipHostStyles;
}

enum TooltipDelay {
  zero = 0,
  medium = 1,
  long = 2,
}

enum TooltipOverflowMode {
  Parent = 0,
  Self = 1,
}

Usage Examples:

import { TooltipHost, TooltipDelay, DirectionalHint, DefaultButton } from "@fluentui/react";

// Basic tooltip
<TooltipHost content="This button saves your changes">
  <DefaultButton text="Save" />
</TooltipHost>

// Tooltip with custom positioning and delay
<TooltipHost
  content="Click to upload files from your computer"
  directionalHint={DirectionalHint.topCenter}
  delay={TooltipDelay.medium}
>
  <DefaultButton text="Upload" iconProps={{ iconName: 'Upload' }} />
</TooltipHost>

// Rich tooltip content
<TooltipHost
  content={
    <div>
      <strong>Advanced Search</strong>
      <div>Use operators like AND, OR, NOT</div>
      <div>Example: "term1 AND term2"</div>
    </div>
  }
>
  <DefaultButton text="Search Options" />
</TooltipHost>

Teaching Bubble

Educational callout component for onboarding and feature discovery.

/**
 * Educational callout component for onboarding
 * @param props - Teaching bubble properties
 * @returns JSX element for teaching bubble
 */
function TeachingBubble(props: ITeachingBubbleProps): JSX.Element;

/**
 * Teaching bubble content container
 * @param props - Teaching bubble content properties
 * @returns JSX element for teaching bubble content
 */
function TeachingBubbleContent(props: ITeachingBubbleProps): JSX.Element;

interface ITeachingBubbleProps {
  /** Target element */
  target?: Element | string | React.RefObject<Element>;
  /** Primary headline */
  headline?: string;
  /** Body text */
  bodyText?: string;
  /** Dismiss handler */
  onDismiss?: (event?: any) => void;
  /** Has close button */
  hasCloseButton?: boolean;
  /** Close button ARIA label */
  closeButtonAriaLabel?: string;
  /** Has condensed headline */
  hasCondensedHeadline?: boolean;
  /** Illustration image */
  illustrationImage?: IImageProps;
  /** Primary button properties */
  primaryButtonProps?: IButtonProps;
  /** Secondary button properties */
  secondaryButtonProps?: IButtonProps;
  /** Footer content */
  footerContent?: string | JSX.Element;
  /** Whether bubble is wide */
  isWide?: boolean;
  /** Custom styles */
  styles?: ITeachingBubbleStyles;
}

Usage Examples:

import React, { useState, useRef } from "react";
import { 
  TeachingBubble, 
  PrimaryButton, 
  DefaultButton 
} from "@fluentui/react";

function TeachingBubbleExample() {
  const [showTeachingBubble, setShowTeachingBubble] = useState(false);
  const targetRef = useRef<HTMLButtonElement>(null);

  return (
    <>
      <PrimaryButton 
        ref={targetRef}
        text="New Feature" 
        onClick={() => setShowTeachingBubble(true)} 
      />
      
      {showTeachingBubble && (
        <TeachingBubble
          target={targetRef}
          headline="Introducing the new feature!"
          bodyText="This new feature helps you work more efficiently. Click 'Try it' to get started or 'Dismiss' if you want to try it later."
          primaryButtonProps={{
            text: 'Try it',
            onClick: () => {
              console.log('User wants to try the feature');
              setShowTeachingBubble(false);
            }
          }}
          secondaryButtonProps={{
            text: 'Dismiss',
            onClick: () => setShowTeachingBubble(false)
          }}
          onDismiss={() => setShowTeachingBubble(false)}
          hasCloseButton={true}
          closeButtonAriaLabel="Close teaching bubble"
        />
      )}
    </>
  );
}

Positioning Utilities

/**
 * Position callout relative to target
 * @param props - Callout position properties
 * @returns Positioning information
 */
function positionCallout(props: ICalloutPositionProps): ICalloutPositionedInfo;

/**
 * Position card relative to target
 * @param props - Position properties
 * @returns Positioning information
 */
function positionCard(props: IPositionProps): IPositionedData;

/**
 * Generic element positioning utility
 * @param props - Position properties
 * @returns Positioning information
 */
function positionElement(props: IPositionProps): IPositionedData;

/**
 * Get bounds from target window
 * @param target - Target element
 * @returns Window bounds
 */
function getBoundsFromTargetWindow(target: Element): IRectangle;

/**
 * Get maximum height for positioning
 * @param target - Target element
 * @param targetEdge - Target edge
 * @param gapSpace - Gap space
 * @param bounds - Positioning bounds
 * @param coverTarget - Whether to cover target
 * @returns Maximum height
 */
function getMaxHeight(
  target: Element,
  targetEdge: RectangleEdge,
  gapSpace?: number,
  bounds?: IRectangle,
  coverTarget?: boolean
): number;

/**
 * Get opposite edge for positioning
 * @param edge - Rectangle edge
 * @returns Opposite edge
 */
function getOppositeEdge(edge: RectangleEdge): RectangleEdge;

enum RectangleEdge {
  top = 1,
  bottom = -1,
  left = 2,
  right = -2,
}

Coachmark

Guided experience overlay component that highlights UI elements and provides contextual information.

/**
 * Coachmark component for guided user experiences
 * @param props - Coachmark properties
 * @returns JSX element for coachmark
 */
function Coachmark(props: ICoachmarkProps): JSX.Element;

interface ICoachmarkProps {
  /** Target element to attach coachmark to */
  target: Element | MouseEvent | Point | string | null;
  /** Position relative to target */
  positioningContainerProps?: IPositioningContainerProps;
  /** Whether coachmark is visible */
  isCollapsed?: boolean;
  /** Delay before showing coachmark */
  delayBeforeMouseOpen?: number;
  /** Delay before hiding coachmark */
  delayBeforeCoachmarkAnimation?: number;
  /** Whether to prevent focus return */
  preventFocusOnMount?: boolean;
  /** Whether to persist on scroll */
  persistOnScroll?: boolean;
  /** Mouse enter event handler */
  onMouseEnter?: (ev: MouseEvent) => void;
  /** Mouse leave event handler */
  onMouseLeave?: (ev: MouseEvent) => void;
  /** Positioning completed callback */
  onPositioned?: (positions?: ICalloutPositionedInfo) => void;
  /** Dismiss callback */
  onDismiss?: (ev?: any) => void;
  /** Custom styles */
  styles?: ICoachmarkStyles;
  /** Theme */
  theme?: ITheme;
  /** Class name */
  className?: string;
}

/** Coachmark attribute name for DOM identification */
const COACHMARK_ATTRIBUTE_NAME = "data-coachmarkid";

Usage Examples:

import { Coachmark, TeachingBubbleContent, DefaultButton } from "@fluentui/react";

function CoachmarkExample() {
  const [showCoachmark, setShowCoachmark] = React.useState(false);
  const targetButton = React.useRef<HTMLButtonElement>(null);

  return (
    <>
      <DefaultButton
        ref={targetButton}
        text="Click me for help"
        onClick={() => setShowCoachmark(true)}
      />
      
      {showCoachmark && (
        <Coachmark
          target={targetButton.current}
          onDismiss={() => setShowCoachmark(false)}
          positioningContainerProps={{
            directionalHint: DirectionalHint.bottomCenter,
            doNotLayer: false,
          }}
        >
          <TeachingBubbleContent
            headline="Welcome to our app!"
            primaryButtonProps={{
              children: 'Got it',
              onClick: () => setShowCoachmark(false),
            }}
            secondaryButtonProps={{
              children: 'Learn more',
              onClick: () => console.log('Learn more clicked'),
            }}
            onDismiss={() => setShowCoachmark(false)}
          >
            This button will help you get started with the main features.
          </TeachingBubbleContent>
        </Coachmark>
      )}
    </>
  );
}