Layout components for organizing content, managing focus, and creating responsive designs. These components provide the foundation for structured layouts and accessibility.
Flexbox-based layout component for arranging elements horizontally or vertically.
/**
* Flexbox-based layout component
* @param props - Stack properties
* @returns JSX element for stack container
*/
function Stack(props: IStackProps): JSX.Element;
/**
* Individual item in stack layout
* @param props - Stack item properties
* @returns JSX element for stack item
*/
function StackItem(props: IStackItemProps): JSX.Element;
interface IStackProps {
/** Whether stack is horizontal */
horizontal?: boolean;
/** Horizontal alignment */
horizontalAlign?: Alignment;
/** Vertical alignment */
verticalAlign?: Alignment;
/** Whether to fill vertical space */
verticalFill?: boolean;
/** Whether items should wrap */
wrap?: boolean;
/** Growing behavior */
grow?: boolean | number;
/** Shrinking behavior */
shrink?: boolean | number;
/** Whether stack is reversed */
reversed?: boolean;
/** Spacing tokens */
tokens?: IStackTokens;
/** Custom styles */
styles?: IStackStyles;
/** Maximum width */
maxWidth?: number | string;
/** Maximum height */
maxHeight?: number | string;
}
interface IStackItemProps {
/** Growing behavior */
grow?: boolean | number;
/** Shrinking behavior */
shrink?: boolean | number;
/** Disable shrinking */
disableShrink?: boolean;
/** Alignment for this item */
align?: Alignment;
/** Order for this item */
order?: number;
/** Spacing tokens */
tokens?: IStackItemTokens;
/** Custom styles */
styles?: IStackItemStyles;
}
interface IStackTokens {
/** Space between child elements */
childrenGap?: number | string;
/** Maximum width */
maxWidth?: number | string;
/** Maximum height */
maxHeight?: number | string;
/** Padding */
padding?: number | string;
}
enum Alignment {
start = 'start',
end = 'end',
center = 'center',
spaceBetween = 'space-between',
spaceAround = 'space-around',
spaceEvenly = 'space-evenly',
baseline = 'baseline',
stretch = 'stretch',
}Usage Examples:
import React from "react";
import { Stack, StackItem, Text, PrimaryButton, DefaultButton } from "@fluentui/react";
function StackExample() {
return (
<div>
{/* Vertical stack with gap */}
<Stack tokens={{ childrenGap: 15 }} styles={{ root: { padding: 20 } }}>
<Text variant="xLarge">Vertical Stack Layout</Text>
<Text>This is a vertical stack with 15px gap between items.</Text>
{/* Horizontal stack for buttons */}
<Stack horizontal tokens={{ childrenGap: 10 }}>
<PrimaryButton text="Primary Action" />
<DefaultButton text="Secondary Action" />
</Stack>
</Stack>
{/* Horizontal stack with alignment */}
<Stack
horizontal
horizontalAlign="space-between"
verticalAlign="center"
styles={{ root: { padding: 20, border: '1px solid #ccc' } }}
>
<Text variant="large">Left Content</Text>
<Text>Center Content</Text>
<Text variant="large">Right Content</Text>
</Stack>
{/* Stack with grow/shrink items */}
<Stack horizontal tokens={{ childrenGap: 10 }} styles={{ root: { padding: 20 } }}>
<StackItem grow={1}>
<div style={{ backgroundColor: '#f3f2f1', padding: 10 }}>
Growing item (flex: 1)
</div>
</StackItem>
<StackItem>
<div style={{ backgroundColor: '#edebe9', padding: 10 }}>
Fixed width item
</div>
</StackItem>
<StackItem grow={2}>
<div style={{ backgroundColor: '#f3f2f1', padding: 10 }}>
Growing item (flex: 2)
</div>
</StackItem>
</Stack>
{/* Wrapped stack */}
<Stack
horizontal
wrap
tokens={{ childrenGap: 10 }}
styles={{ root: { padding: 20, maxWidth: 400 } }}
>
{Array.from({ length: 8 }, (_, i) => (
<div key={i} style={{
backgroundColor: '#deecf9',
padding: '8px 12px',
borderRadius: 4
}}>
Item {i + 1}
</div>
))}
</Stack>
</div>
);
}Root container component that provides design system context and base styles.
/**
* Root container providing design system context
* @param props - Fabric properties
* @returns JSX element for fabric container
*/
function Fabric(props: IFabricProps): JSX.Element;
interface IFabricProps {
/** Component as override */
as?: React.ElementType;
/** Whether to apply base theme */
applyTheme?: boolean;
/** Whether to apply theme to body */
applyThemeToBody?: boolean;
/** Theme to apply */
theme?: IPartialTheme;
/** Custom styles */
styles?: IFabricStyles;
/** Class name */
className?: string;
/** Component ref */
componentRef?: IRefObject<IFabric>;
}Usage Examples:
import { Fabric, createTheme } from "@fluentui/react";
// Basic Fabric wrapper
function App() {
return (
<Fabric>
<div>Your application content</div>
</Fabric>
);
}
// Fabric with custom theme
const customTheme = createTheme({
palette: {
themePrimary: '#0078d4',
},
});
function ThemedApp() {
return (
<Fabric theme={customTheme} applyThemeToBody>
<div>Themed application content</div>
</Fabric>
);
}Scrollable container with sticky elements and scroll event management.
/**
* Scrollable container with sticky elements
* @param props - Scrollable pane properties
* @returns JSX element for scrollable pane
*/
function ScrollablePane(props: IScrollablePaneProps): JSX.Element;
interface IScrollablePaneProps {
/** Scroll bar visibility */
scrollbarVisibility?: ScrollbarVisibility;
/** Custom styles */
styles?: IScrollablePaneStyles;
/** Class name */
className?: string;
/** Component ref */
componentRef?: IRefObject<IScrollablePane>;
/** Initial scroll position */
initialScrollPosition?: number;
}
enum ScrollbarVisibility {
auto = 0,
always = 1,
}
/**
* Scrollable pane context for sticky elements
*/
const ScrollablePaneContext: React.Context<{
scrollablePane?: {
subscribe: (handler: (container: HTMLElement, stickyContainer: HTMLElement) => void) => void;
unsubscribe: (handler: (container: HTMLElement, stickyContainer: HTMLElement) => void) => void;
addSticky: (sticky: ISticky) => void;
removeSticky: (sticky: ISticky) => void;
updateStickyRefHeights: () => void;
sortSticky: (sticky: ISticky, isAdd?: boolean) => void;
notifySubscribers: () => void;
};
}>;Usage Examples:
import React from "react";
import { ScrollablePane, Sticky, StickyPositionType, DetailsList } from "@fluentui/react";
function ScrollablePaneExample() {
const items = Array.from({ length: 100 }, (_, i) => ({
key: i,
name: `Item ${i + 1}`,
value: Math.floor(Math.random() * 100),
}));
const columns = [
{ key: 'name', name: 'Name', fieldName: 'name', minWidth: 100 },
{ key: 'value', name: 'Value', fieldName: 'value', minWidth: 100 },
];
return (
<div style={{ height: 400, position: 'relative', border: '1px solid #ccc' }}>
<ScrollablePane>
<Sticky stickyPosition={StickyPositionType.Header}>
<div style={{
backgroundColor: '#f8f8f8',
padding: 10,
borderBottom: '1px solid #ccc'
}}>
Sticky Header - Always visible at top
</div>
</Sticky>
<div style={{ padding: 20 }}>
<h3>Scrollable Content</h3>
<DetailsList
items={items}
columns={columns}
layoutMode={DetailsListLayoutMode.justified}
/>
</div>
<Sticky stickyPosition={StickyPositionType.Footer}>
<div style={{
backgroundColor: '#f8f8f8',
padding: 10,
borderTop: '1px solid #ccc'
}}>
Sticky Footer - Always visible at bottom
</div>
</Sticky>
</ScrollablePane>
</div>
);
}Container that manages focus navigation with keyboard support.
/**
* Container managing focus navigation
* @param props - Focus zone properties
* @returns JSX element for focus zone
*/
function FocusZone(props: IFocusZoneProps): JSX.Element;
interface IFocusZoneProps {
/** Component as override */
as?: React.ElementType;
/** Focus zone direction */
direction?: FocusZoneDirection;
/** Default tabbable element */
defaultTabbableElement?: string | HTMLElement;
/** Default active element */
defaultActiveElement?: string | HTMLElement;
/** Whether to disable tab key */
disabled?: boolean;
/** Check for data-no-vertical-wrap attribute */
checkForNoWrap?: boolean;
/** Allow focus root */
allowFocusRoot?: boolean;
/** Allow tab key */
allowTabKey?: boolean;
/** Circular navigation */
isCircularNavigation?: boolean;
/** Handle tab key */
handleTabKey?: FocusZoneTabbableElements;
/** Focus on mount */
shouldFocusOnMount?: boolean;
/** Should input lose focus on arrow key */
shouldInputLoseFocusOnArrowKey?: (inputElement: HTMLInputElement) => boolean;
/** Active element changed handler */
onActiveElementChanged?: (element?: HTMLElement, event?: React.FocusEvent<HTMLElement>) => void;
/** Focus zone active */
onFocusNotification?: () => void;
/** Zone ID */
id?: string;
/** Custom styles */
styles?: any;
/** Component ref */
componentRef?: IRefObject<IFocusZone>;
}
enum FocusZoneDirection {
vertical = 0,
horizontal = 1,
bidirectional = 2,
domOrder = 3,
}
enum FocusZoneTabbableElements {
none = 0,
all = 1,
inputOnly = 2,
}Usage Examples:
import React from "react";
import { FocusZone, FocusZoneDirection, PrimaryButton, DefaultButton } from "@fluentui/react";
function FocusZoneExample() {
return (
<div>
{/* Horizontal focus zone */}
<h3>Horizontal Navigation (Arrow Keys)</h3>
<FocusZone direction={FocusZoneDirection.horizontal}>
<div style={{ display: 'flex', gap: 10, padding: 10, border: '1px solid #ccc' }}>
<PrimaryButton text="Button 1" />
<DefaultButton text="Button 2" />
<DefaultButton text="Button 3" />
<DefaultButton text="Button 4" />
</div>
</FocusZone>
{/* Vertical focus zone */}
<h3>Vertical Navigation (Arrow Keys)</h3>
<FocusZone direction={FocusZoneDirection.vertical}>
<div style={{ display: 'flex', flexDirection: 'column', gap: 10, padding: 10, border: '1px solid #ccc', width: 200 }}>
<PrimaryButton text="First Item" />
<DefaultButton text="Second Item" />
<DefaultButton text="Third Item" />
<DefaultButton text="Fourth Item" />
</div>
</FocusZone>
{/* Bidirectional focus zone */}
<h3>Grid Navigation (Arrow Keys)</h3>
<FocusZone direction={FocusZoneDirection.bidirectional}>
<div style={{
display: 'grid',
gridTemplateColumns: 'repeat(3, 1fr)',
gap: 10,
padding: 10,
border: '1px solid #ccc',
width: 300
}}>
{Array.from({ length: 9 }, (_, i) => (
<DefaultButton key={i} text={`Item ${i + 1}`} />
))}
</div>
</FocusZone>
</div>
);
}Container that traps focus within its boundaries for modal scenarios.
/**
* Container that traps focus within boundaries
* @param props - Focus trap zone properties
* @returns JSX element for focus trap zone
*/
function FocusTrapZone(props: IFocusTrapZoneProps): JSX.Element;
interface IFocusTrapZoneProps {
/** Component as override */
as?: React.ElementType;
/** Whether focus trap is disabled */
disabled?: boolean;
/** Whether to ignore external focusing */
ignoreExternalFocusing?: boolean;
/** Force focus inside trap */
forceFocusInsideTrap?: boolean;
/** First focusable selector */
firstFocusableSelector?: string | (() => string);
/** Last focusable selector */
lastFocusableSelector?: string | (() => string);
/** Focus previous on tab */
focusPreviousOnLastElement?: boolean;
/** Focus next on shift tab */
focusNextOnFirstElement?: boolean;
/** Component ref */
componentRef?: IRefObject<IFocusTrapZone>;
}Usage Examples:
import React, { useState } from "react";
import {
FocusTrapZone,
PrimaryButton,
DefaultButton,
TextField,
Modal
} from "@fluentui/react";
function FocusTrapExample() {
const [isModalOpen, setIsModalOpen] = useState(false);
return (
<>
<PrimaryButton
text="Open Modal with Focus Trap"
onClick={() => setIsModalOpen(true)}
/>
<Modal
isOpen={isModalOpen}
onDismiss={() => setIsModalOpen(false)}
>
<FocusTrapZone>
<div style={{ padding: 20, minWidth: 400 }}>
<h2>Modal with Focus Trap</h2>
<p>Focus is trapped within this modal. Tab through the elements:</p>
<TextField label="First Name" />
<TextField label="Last Name" />
<TextField label="Email" />
<div style={{ marginTop: 20, display: 'flex', gap: 10 }}>
<PrimaryButton
text="Save"
onClick={() => setIsModalOpen(false)}
/>
<DefaultButton
text="Cancel"
onClick={() => setIsModalOpen(false)}
/>
</div>
</div>
</FocusTrapZone>
</Modal>
</>
);
}Component that handles responsive resizing of child elements.
/**
* Component handling responsive resizing
* @param props - Resize group properties
* @returns JSX element for resize group
*/
function ResizeGroup(props: IResizeGroupProps): JSX.Element;
interface IResizeGroupProps {
/** Data to be passed to onRenderData */
data?: any;
/** Render function for the data */
onRenderData: (data: any) => JSX.Element;
/** Function to reduce the data when there's not enough space */
onReduceData: (currentData: any) => any | undefined;
/** Function to grow the data when there's more space available */
onGrowData?: (currentData: any) => any | undefined;
/** Cache key for measurements */
dataDidRender?: (renderedData: any) => void;
/** Component styles */
styles?: IResizeGroupStyles;
/** Component ref */
componentRef?: IRefObject<IResizeGroup>;
}
enum ResizeGroupDirection {
horizontal = 0,
vertical = 1,
}
/**
* Get measurement cache for resize group
* @returns Measurement cache
*/
function getMeasurementCache(): { [key: string]: number };
/**
* Get next resize group state provider
* @param getMeasuredElementWidthStub - Stub for measuring element width
* @returns State provider function
*/
function getNextResizeGroupStateProvider(
getMeasuredElementWidthStub?: (element: HTMLElement) => number
): (props: IResizeGroupProps, currentState: IResizeGroupState) => IResizeGroupState | undefined;
/**
* Measured context for resize group optimization
*/
const MeasuredContext: React.Context<{
isMeasured?: boolean;
}>;Component that sticks to viewport during scroll within scrollable pane.
/**
* Component that sticks to viewport during scroll
* @param props - Sticky properties
* @returns JSX element for sticky component
*/
function Sticky(props: IStickyProps): JSX.Element;
interface IStickyProps {
/** Sticky position type */
stickyPosition?: StickyPositionType;
/** Sticky background color */
stickyBackgroundColor?: string;
/** Sticky class name */
stickyClassName?: string;
/** Custom styles */
styles?: any;
/** Component ref */
componentRef?: IRefObject<ISticky>;
}
enum StickyPositionType {
Both = 0,
Header = 1,
Footer = 2,
}/**
* Layer component for portal rendering
* @param props - Layer properties
* @returns JSX element for layer
*/
function Layer(props: ILayerProps): JSX.Element;
/**
* Layer host for managing layers
* @param props - Layer host properties
* @returns JSX element for layer host
*/
function LayerHost(props: ILayerHostProps): JSX.Element;
/**
* Get layer styles
* @param props - Layer style properties
* @returns Layer styles
*/
function getLayerStyles(props: ILayerStyleProps): ILayerStyles;
/**
* Register layer
* @param hostId - Host ID
* @param layer - Layer element
*/
function registerLayer(hostId: string, layer: HTMLElement): void;
/**
* Unregister layer
* @param hostId - Host ID
* @param layer - Layer element
*/
function unregisterLayer(hostId: string, layer: HTMLElement): void;
/**
* Get layer count
* @returns Number of layers
*/
function getLayerCount(): number;
interface ILayerProps {
/** Host ID for layer */
hostId?: string;
/** Event bubbling */
eventBubblingEnabled?: boolean;
/** Custom styles */
styles?: ILayerStyles;
/** Component ref */
componentRef?: IRefObject<ILayer>;
}Visual separator component for creating vertical divisions in layouts.
/**
* Vertical divider component for layout separation
* @param props - Vertical divider properties
* @returns JSX element for vertical divider
*/
function VerticalDivider(props: IVerticalDividerProps): JSX.Element;
interface IVerticalDividerProps {
/** Class name */
className?: string;
/** Custom styles */
styles?: IVerticalDividerStyles;
/** Theme */
theme?: ITheme;
/** Component ref */
componentRef?: IRefObject<IVerticalDivider>;
}Usage Examples:
import { VerticalDivider, Stack } from "@fluentui/react";
// Basic vertical divider in a horizontal stack
<Stack horizontal tokens={{ childrenGap: 20 }}>
<div>Left content</div>
<VerticalDivider />
<div>Right content</div>
</Stack>
// Multiple sections with dividers
<Stack horizontal tokens={{ childrenGap: 15 }}>
<div>Section 1</div>
<VerticalDivider />
<div>Section 2</div>
<VerticalDivider />
<div>Section 3</div>
</Stack>
// Custom styled divider
<Stack horizontal verticalAlign="center">
<span>Before</span>
<VerticalDivider
styles={{
wrapper: {
height: 40,
margin: '0 20px'
}
}}
/>
<span>After</span>
</Stack>