Comprehensive React component library implementing Microsoft's Fluent Design System for building Office 365 experiences
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Modal and non-modal overlay components including dialogs, panels, callouts, and tooltips for displaying contextual information and actions over the main application content.
Slide-out side panel component for displaying detailed information or secondary actions without navigating away from the current context.
/**
* Slide-out side panel component
*/
function Panel(props: IPanelProps): JSX.Element;
interface IPanel {
/** Open the panel */
open(): void;
/** Dismiss/close the panel */
dismiss(): void;
}
interface IPanelProps {
/** Reference to access component methods */
componentRef?: IRefObject<IPanel>;
/** Whether the panel is open */
isOpen?: boolean;
/** Whether the panel has a close button */
hasCloseButton?: boolean;
/** Whether clicking outside dismisses the panel */
isLightDismiss?: boolean;
/** Whether the panel is hidden when dismissed */
isHiddenOnDismiss?: boolean;
/** Whether the panel blocks interaction with main content */
isBlocking?: boolean;
/** Size/type of the panel */
type?: PanelType;
/** Custom width for custom panel type */
customWidth?: string;
/** Header text */
headerText?: string;
/** Properties for the header text element */
headerTextProps?: React.HTMLProps<HTMLDivElement>;
/** ARIA label for close button */
closeButtonAriaLabel?: string;
/** Whether panel is at the bottom on small screens */
isFooterAtBottom?: boolean;
/** Whether to show a subtle animation */
hasCloseButton?: boolean;
/** Layer properties */
layerProps?: ILayerProps;
/** Overlay properties */
overlayProps?: IOverlayProps;
/** Custom render function for navigation */
onRenderNavigation?: IRenderFunction<IPanelProps>;
/** Custom render function for header */
onRenderHeader?: IRenderFunction<IPanelProps>;
/** Custom render function for body */
onRenderBody?: IRenderFunction<IPanelProps>;
/** Custom render function for footer */
onRenderFooter?: IRenderFunction<IPanelProps>;
/** Custom render function for footer content */
onRenderFooterContent?: IRenderFunction<IPanelProps>;
/** Callback fired when panel is dismissed */
onDismiss?: (ev?: React.SyntheticEvent<HTMLElement>) => void;
/** Callback fired when panel opens */
onOpened?: () => void;
/** Callback fired when panel starts opening */
onOpening?: () => void;
/** Callback fired before panel dismisses */
onDismissed?: () => void;
/** Custom styles */
styles?: IStyleFunctionOrObject<IPanelStyleProps, IPanelStyles>;
/** Theme provided by higher-order component */
theme?: ITheme;
/** Additional CSS class */
className?: string;
/** Child content */
children?: React.ReactNode;
}
enum PanelType {
smallFluid = 0,
smallFixedFar = 1,
smallFixedNear = 2,
medium = 3,
large = 4,
largeFixed = 5,
extraLarge = 6,
custom = 99
}Usage Examples:
import React, { useState } from "react";
import { Panel, PanelType, PrimaryButton, DefaultButton } from "office-ui-fabric-react";
function BasicPanel() {
const [isOpen, setIsOpen] = useState(false);
return (
<div>
<PrimaryButton text="Open Panel" onClick={() => setIsOpen(true)} />
<Panel
isOpen={isOpen}
onDismiss={() => setIsOpen(false)}
headerText="Panel Title"
type={PanelType.medium}
closeButtonAriaLabel="Close panel"
>
<div>
<p>Panel content goes here.</p>
<DefaultButton text="Action" onClick={() => console.log("Action clicked")} />
</div>
</Panel>
</div>
);
}
function CustomPanel() {
const [isOpen, setIsOpen] = useState(false);
return (
<div>
<PrimaryButton text="Open Custom Panel" onClick={() => setIsOpen(true)} />
<Panel
isOpen={isOpen}
onDismiss={() => setIsOpen(false)}
type={PanelType.custom}
customWidth="600px"
headerText="Custom Width Panel"
isLightDismiss
onRenderFooter={() => (
<div style={{ padding: "16px", borderTop: "1px solid #edebe9" }}>
<PrimaryButton
text="Save"
onClick={() => {
console.log("Save clicked");
setIsOpen(false);
}}
/>
<DefaultButton
text="Cancel"
onClick={() => setIsOpen(false)}
style={{ marginLeft: 8 }}
/>
</div>
)}
>
<div style={{ padding: "16px" }}>
<p>Custom panel with footer actions.</p>
</div>
</Panel>
</div>
);
}Modal dialog component for displaying important information or collecting user input that requires immediate attention.
/**
* Modal dialog component for critical interactions
*/
function Dialog(props: IDialogProps): JSX.Element;
/**
* Content area of the dialog
*/
function DialogContent(props: IDialogContentProps): JSX.Element;
/**
* Footer area for dialog actions
*/
function DialogFooter(props: IDialogFooterProps): JSX.Element;
interface IDialog {
/** Focus on the dialog */
focus(): void;
}
interface IDialogProps {
/** Reference to access component methods */
componentRef?: IRefObject<IDialog>;
/** Whether the dialog is open */
isOpen?: boolean;
/** Whether the dialog blocks interaction with page */
isBlocking?: boolean;
/** Whether to use dark overlay */
isDarkOverlay?: boolean;
/** Dialog type */
type?: DialogType;
/** Maximum width of the dialog */
maxWidth?: number | string;
/** Minimum width of the dialog */
minWidth?: number | string;
/** Whether dialog is hidden on dismiss */
hidden?: boolean;
/** Modal properties */
modalProps?: IModalProps;
/** Title of the dialog */
title?: string;
/** Subtitle text */
subText?: string;
/** Content class name */
contentClassName?: string;
/** Top button properties */
topButtonsProps?: IButtonProps[];
/** Custom render function for title */
onRenderTitle?: IRenderFunction<IDialogProps>;
/** Custom render function for sub text */
onRenderSubText?: IRenderFunction<IDialogProps>;
/** Callback fired when dialog is dismissed */
onDismiss?: (ev?: React.MouseEvent<HTMLButtonElement>) => void;
/** Custom styles */
styles?: IStyleFunctionOrObject<IDialogStyleProps, IDialogStyles>;
/** Theme provided by higher-order component */
theme?: ITheme;
/** Additional CSS class */
className?: string;
/** Child content */
children?: React.ReactNode;
}
interface IDialogContentProps {
/** Reference to access component methods */
componentRef?: IRefObject<IDialogContent>;
/** Dialog title */
title?: string;
/** Dialog subtitle */
subText?: string;
/** Whether to show close button */
showCloseButton?: boolean;
/** Close button ARIA label */
closeButtonAriaLabel?: string;
/** Top button properties */
topButtonsProps?: IButtonProps[];
/** Custom render function for title */
onRenderTitle?: IRenderFunction<IDialogContentProps>;
/** Custom render function for sub text */
onRenderSubText?: IRenderFunction<IDialogContentProps>;
/** Callback fired when close button is clicked */
onDismiss?: (ev?: React.MouseEvent<HTMLButtonElement>) => void;
/** Custom styles */
styles?: IStyleFunctionOrObject<IDialogContentStyleProps, IDialogContentStyles>;
/** Theme provided by higher-order component */
theme?: ITheme;
/** Additional CSS class */
className?: string;
/** Child content */
children?: React.ReactNode;
}
interface IDialogFooterProps {
/** Reference to access component methods */
componentRef?: IRefObject<IDialogFooter>;
/** Custom styles */
styles?: IStyleFunctionOrObject<IDialogFooterStyleProps, IDialogFooterStyles>;
/** Theme provided by higher-order component */
theme?: ITheme;
/** Additional CSS class */
className?: string;
/** Child content (usually buttons) */
children?: React.ReactNode;
}
enum DialogType {
normal = 0,
largeHeader = 1,
close = 2
}Base modal component providing overlay functionality and focus management for dialog-like components.
/**
* Base modal component for overlay functionality
*/
function Modal(props: IModalProps): JSX.Element;
interface IModal {
/** Focus on the modal */
focus(): void;
}
interface IModalProps {
/** Reference to access component methods */
componentRef?: IRefObject<IModal>;
/** Whether the modal is open */
isOpen?: boolean;
/** Whether the modal blocks interaction */
isBlocking?: boolean;
/** Whether to use dark overlay */
isDarkOverlay?: boolean;
/** Whether the modal is modeless */
isModeless?: boolean;
/** Container class name */
containerClassName?: string;
/** Scrollable content class name */
scrollableContentClassName?: string;
/** Drag options */
dragOptions?: IDragOptions;
/** Whether to enable touch bodyScroll */
enableAriaHiddenSiblings?: boolean;
/** Layer properties */
layerProps?: ILayerProps;
/** Overlay properties */
overlayProps?: IOverlayProps;
/** Title ID for ARIA */
titleAriaId?: string;
/** Subtitle ID for ARIA */
subtitleAriaId?: string;
/** Top offset */
topOffsetFixed?: boolean;
/** Custom render function for title */
onLayerDidMount?: () => void;
/** Callback fired when modal is dismissed */
onDismiss?: (ev?: React.MouseEvent<HTMLButtonElement>) => void;
/** Callback fired when modal is dismissed with overlay click */
onDismissed?: () => void;
/** Custom styles */
styles?: IStyleFunctionOrObject<IModalStyleProps, IModalStyles>;
/** Theme provided by higher-order component */
theme?: ITheme;
/** Additional CSS class */
className?: string;
/** Child content */
children?: React.ReactNode;
}Positioned overlay component for displaying contextual information relative to a target element.
/**
* Positioned overlay component for contextual information
*/
function Callout(props: ICalloutProps): JSX.Element;
interface ICallout {
/** Dismiss the callout */
dismiss(ev?: any): void;
}
interface ICalloutProps {
/** Reference to access component methods */
componentRef?: IRefObject<ICallout>;
/** Target element or selector for positioning */
target?: Element | string | MouseEvent | React.RefObject<Element> | Point;
/** Directional hint for positioning */
directionalHint?: DirectionalHint;
/** Whether to use target width */
useTargetWidth?: boolean;
/** Whether to cover the target */
coverTarget?: boolean;
/** Gap between callout and target */
gapSpace?: number;
/** Beak width */
beakWidth?: number;
/** Minimum page padding */
minPagePadding?: number;
/** Whether the callout is hidden */
hidden?: boolean;
/** Role for accessibility */
role?: string;
/** ARIA label */
ariaLabel?: string;
/** ARIA labelledby */
ariaLabelledBy?: string;
/** ARIA describedby */
ariaDescribedBy?: string;
/** Set initial focus */
setInitialFocus?: boolean;
/** Whether to disable animation */
doNotLayer?: boolean;
/** Directional hint for RTL */
directionalHintForRTL?: DirectionalHint;
/** Callback fired when callout is positioned */
onPositioned?: (positions?: ICalloutPositionedInfo) => void;
/** Callback fired when callout is dismissed */
onDismiss?: (ev?: any) => void;
/** Callback fired when scroll occurs */
onScroll?: () => void;
/** Callback fired when callout tries to close */
onRestoreFocus?: () => void;
/** Custom styles */
styles?: IStyleFunctionOrObject<ICalloutContentStyleProps, ICalloutContentStyles>;
/** Theme provided by higher-order component */
theme?: ITheme;
/** Additional CSS class */
className?: string;
/** Callout bounds */
bounds?: IRectangle;
/** Background color */
backgroundColor?: string;
/** Prevention of dismiss on scroll */
preventDismissOnScroll?: boolean;
/** Prevention of dismiss on resize */
preventDismissOnResize?: boolean;
/** Prevention of dismiss on lost focus */
preventDismissOnLostFocus?: boolean;
/** Focus trap zone properties */
focusTrapZoneProps?: IFocusTrapZoneProps;
/** Whether to hide overflow */
hideOverflow?: boolean;
/** Child content */
children?: React.ReactNode;
}
enum DirectionalHint {
topLeftEdge = 0,
topCenter = 1,
topRightEdge = 2,
topAutoEdge = 3,
bottomLeftEdge = 4,
bottomCenter = 5,
bottomRightEdge = 6,
bottomAutoEdge = 7,
leftTopEdge = 8,
leftCenter = 9,
leftBottomEdge = 10,
rightTopEdge = 11,
rightCenter = 12,
rightBottomEdge = 13
}Simple tooltip component for providing brief contextual information on hover or focus.
/**
* Simple tooltip for brief contextual information
*/
function Tooltip(props: ITooltipProps): JSX.Element;
/**
* Advanced tooltip host with overflow detection
*/
function TooltipHost(props: ITooltipHostProps): JSX.Element;
interface ITooltip {
/** Current tooltip props */
props: ITooltipProps;
}
interface ITooltipProps {
/** Reference to access component methods */
componentRef?: IRefObject<ITooltip>;
/** Content to display in tooltip */
content?: string | React.ReactNode;
/** Maximum width of tooltip */
maxWidth?: string | number;
/** Target ID for the tooltip */
targetElement?: HTMLElement;
/** Directional hint */
directionalHint?: DirectionalHint;
/** Gap space */
gapSpace?: number;
/** Beak width */
beakWidth?: number;
/** Delay before showing */
delay?: TooltipDelay;
/** Callout properties */
calloutProps?: ICalloutProps;
/** Custom render function for content */
onRenderContent?: IRenderFunction<ITooltipProps>;
/** Custom styles */
styles?: IStyleFunctionOrObject<ITooltipStyleProps, ITooltipStyles>;
/** Theme provided by higher-order component */
theme?: ITheme;
/** Additional CSS class */
className?: string;
}
interface ITooltipHostProps {
/** Reference to access component methods */
componentRef?: IRefObject<ITooltipHost>;
/** Content to display in tooltip */
content?: string | React.ReactNode;
/** Whether to show tooltip on overflow only */
overflowMode?: TooltipOverflowMode;
/** Maximum width of tooltip */
maxWidth?: string | number;
/** Directional hint */
directionalHint?: DirectionalHint;
/** Gap space */
gapSpace?: number;
/** Delay before showing */
delay?: TooltipDelay;
/** ID for the tooltip */
id?: string;
/** ARIA describedby */
setAriaDescribedBy?: boolean;
/** Tooltip properties */
tooltipProps?: ITooltipProps;
/** Callout properties */
calloutProps?: ICalloutProps;
/** Host class name */
hostClassName?: string;
/** Custom styles */
styles?: IStyleFunctionOrObject<ITooltipHostStyleProps, ITooltipHostStyles>;
/** Theme provided by higher-order component */
theme?: ITheme;
/** Additional CSS class */
className?: string;
/** Child content */
children?: React.ReactNode;
}
enum TooltipOverflowMode {
Parent = 0,
Self = 1
}
enum TooltipDelay {
zero = 0,
medium = 1,
long = 2
}Usage Examples:
import React, { useState } from "react";
import {
Dialog,
DialogContent,
DialogFooter,
Callout,
TooltipHost,
PrimaryButton,
DefaultButton,
DirectionalHint
} from "office-ui-fabric-react";
function DialogExample() {
const [isDialogOpen, setIsDialogOpen] = useState(false);
return (
<div>
<PrimaryButton text="Open Dialog" onClick={() => setIsDialogOpen(true)} />
<Dialog
isOpen={isDialogOpen}
onDismiss={() => setIsDialogOpen(false)}
isBlocking={false}
maxWidth={500}
>
<DialogContent
title="Confirm Action"
subText="Are you sure you want to proceed with this action?"
onDismiss={() => setIsDialogOpen(false)}
showCloseButton
>
<div>
<p>Additional details about the action can go here.</p>
</div>
</DialogContent>
<DialogFooter>
<PrimaryButton
text="Confirm"
onClick={() => {
console.log("Confirmed");
setIsDialogOpen(false);
}}
/>
<DefaultButton
text="Cancel"
onClick={() => setIsDialogOpen(false)}
/>
</DialogFooter>
</Dialog>
</div>
);
}
function CalloutExample() {
const [isCalloutVisible, setIsCalloutVisible] = useState(false);
const buttonRef = React.useRef<HTMLButtonElement>(null);
return (
<div>
<DefaultButton
ref={buttonRef}
text="Show Callout"
onClick={() => setIsCalloutVisible(!isCalloutVisible)}
/>
{isCalloutVisible && (
<Callout
target={buttonRef.current}
onDismiss={() => setIsCalloutVisible(false)}
directionalHint={DirectionalHint.bottomCenter}
setInitialFocus
>
<div style={{ padding: 16, maxWidth: 200 }}>
<h3>Callout Title</h3>
<p>This is the callout content with more detailed information.</p>
<DefaultButton
text="Close"
onClick={() => setIsCalloutVisible(false)}
/>
</div>
</Callout>
)}
</div>
);
}
function TooltipExample() {
return (
<div>
<TooltipHost content="This is a helpful tooltip">
<DefaultButton text="Hover for tooltip" />
</TooltipHost>
<TooltipHost
content="This tooltip only shows when text overflows"
overflowMode={TooltipOverflowMode.Self}
>
<div style={{ width: 100, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
This is a very long text that will be truncated
</div>
</TooltipHost>
</div>
);
}// Common overlay interfaces
interface IOverlayProps {
/** Whether overlay is dark */
isDarkThemed?: boolean;
/** Click handler */
onClick?: () => void;
/** Custom styles */
styles?: IStyleFunctionOrObject<IOverlayStyleProps, IOverlayStyles>;
/** Theme */
theme?: ITheme;
/** CSS class */
className?: string;
}
interface ILayerProps {
/** Host ID */
hostId?: string;
/** Event bus ID */
eventBubblingEnabled?: boolean;
/** Custom styles */
styles?: IStyleFunctionOrObject<ILayerStyleProps, ILayerStyles>;
/** Theme */
theme?: ITheme;
/** CSS class */
className?: string;
/** Callback when layer mounts */
onLayerDidMount?: () => void;
/** Callback when layer unmounts */
onLayerWillUnmount?: () => void;
}
interface IFocusTrapZoneProps {
/** Whether focus trap is disabled */
disabled?: boolean;
/** Element to focus initially */
firstFocusableSelector?: string;
/** Whether to force focus into zone */
forceFocusInsideTrap?: boolean;
/** Whether focus wraps around */
isClickableOutsideFocusTrap?: boolean;
/** Whether to ignore external focus */
ignoreExternalFocusing?: boolean;
/** Focus callback */
onFocus?: (event: React.FocusEvent<HTMLElement>) => void;
/** Blur callback */
onBlur?: (event: React.FocusEvent<HTMLElement>) => void;
}
// Positioning interfaces
interface Point {
x: number;
y: number;
}
interface IRectangle {
left: number;
top: number;
width: number;
height: number;
right?: number;
bottom?: number;
}
interface ICalloutPositionedInfo {
positions?: ICalloutPosition;
calloutMaxHeight?: number;
}
interface ICalloutPosition {
directionalHint?: DirectionalHint;
directionalHintFixed?: boolean;
alignmentEdge?: RectangleEdge;
targetEdge?: RectangleEdge;
}
enum RectangleEdge {
top = 1,
bottom = -1,
left = 2,
right = -2
}Install with Tessl CLI
npx tessl i tessl/npm-office-ui-fabric-react