Footer components and toolbar utilities for actions, navigation, and content display at the bottom of pages and layouts.
Sticky footer toolbar component that provides a consistent action area at the bottom of pages with responsive width calculation.
/**
* Sticky footer toolbar for actions and extra content
* @param props - Footer toolbar configuration
* @returns React element with footer toolbar
*/
function FooterToolbar(props: FooterToolbarProps): React.ReactElement;
interface FooterToolbarProps {
/** Extra content area displayed on the right */
extra?: React.ReactNode;
/** Custom CSS styles */
style?: React.CSSProperties;
/** CSS class name */
className?: string;
/** Custom content renderer with full control over rendering */
renderContent?: (
props: FooterToolbarProps & RouteContextType & { leftWidth?: string },
dom: JSX.Element
) => React.ReactNode;
/** CSS class prefix for styling */
prefixCls?: string;
/** Custom styling function */
stylish?: GenerateStyle<FooterToolBarToken>;
/** Main content (typically action buttons) */
children?: React.ReactNode;
/** Enable/disable portal DOM rendering (default: true) */
portalDom?: boolean;
}
interface FooterToolBarToken {
/** Footer toolbar height */
footerToolbarHeight?: number;
/** Footer toolbar padding */
footerToolbarPadding?: number;
/** Footer toolbar background color */
footerToolbarBg?: string;
/** Footer toolbar border color */
footerToolbarBorderColor?: string;
}Usage Examples:
import React from "react";
import { FooterToolbar } from "@ant-design/pro-layout";
import { Button, Space } from "antd";
// Basic footer toolbar
function BasicFooterToolbar() {
return (
<FooterToolbar
extra={<div>Extra information</div>}
>
<Space>
<Button>Cancel</Button>
<Button type="primary">Submit</Button>
</Space>
</FooterToolbar>
);
}
// Form footer toolbar
function FormFooterToolbar() {
const [loading, setLoading] = React.useState(false);
const handleSubmit = async () => {
setLoading(true);
// Simulate API call
await new Promise(resolve => setTimeout(resolve, 2000));
setLoading(false);
};
return (
<FooterToolbar
extra={<div>All changes are automatically saved</div>}
>
<Space>
<Button>Reset</Button>
<Button type="primary" loading={loading} onClick={handleSubmit}>
Save Changes
</Button>
</Space>
</FooterToolbar>
);
}
// Custom rendered footer toolbar
function CustomFooterToolbar() {
return (
<FooterToolbar
renderContent={(props, dom) => (
<div style={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
background: 'linear-gradient(90deg, #1890ff, #722ed1)',
color: 'white',
padding: '0 24px',
}}>
<div>Custom footer with gradient background</div>
<Space>
<Button ghost>Action 1</Button>
<Button ghost>Action 2</Button>
</Space>
</div>
)}
/>
);
}
// Footer toolbar without portal (renders in place)
function InlineFooterToolbar() {
return (
<div style={{ position: 'relative', minHeight: '400px' }}>
<div>Page content...</div>
<FooterToolbar portalDom={false}>
<Button type="primary">In-place Action</Button>
</FooterToolbar>
</div>
);
}Standard footer component with links, copyright information, and company branding.
/**
* Default footer component with links and copyright
* @param props - Footer configuration
* @returns React element with footer content
*/
function DefaultFooter(props: FooterProps): React.ReactElement;
interface FooterProps {
/** Footer links array */
links?: FooterLink[];
/** Copyright information */
copyright?: React.ReactNode;
/** CSS class name */
className?: string;
/** Custom CSS styles */
style?: React.CSSProperties;
}
interface FooterLink {
/** Link key for React */
key?: string;
/** Link title/text */
title: React.ReactNode;
/** Link URL */
href?: string;
/** Link target */
target?: string;
}Usage Examples:
import React from "react";
import { DefaultFooter } from "@ant-design/pro-layout";
// Basic default footer
function BasicDefaultFooter() {
return (
<DefaultFooter
copyright="© 2023 My Company. All rights reserved."
links={[
{ key: 'about', title: 'About Us', href: '/about' },
{ key: 'privacy', title: 'Privacy Policy', href: '/privacy' },
{ key: 'terms', title: 'Terms of Service', href: '/terms' },
{ key: 'contact', title: 'Contact', href: '/contact' },
]}
/>
);
}
// Footer with external links
function ExternalLinksFooter() {
return (
<DefaultFooter
copyright="© 2023 Enterprise Corp."
links={[
{
key: 'github',
title: 'GitHub',
href: 'https://github.com/company',
target: '_blank'
},
{
key: 'docs',
title: 'Documentation',
href: 'https://docs.company.com',
target: '_blank'
},
{
key: 'support',
title: 'Support',
href: 'mailto:support@company.com'
},
]}
/>
);
}
// Footer with custom copyright
function CustomCopyrightFooter() {
return (
<DefaultFooter
copyright={
<div>
© 2023 <strong>My Company</strong>.
Built with ❤️ using{' '}
<a href="https://ant.design" target="_blank" rel="noopener noreferrer">
Ant Design
</a>
</div>
}
links={[
{ key: 'help', title: 'Help Center', href: '/help' },
{ key: 'feedback', title: 'Feedback', href: '/feedback' },
]}
/>
);
}The footer components integrate seamlessly with ProLayout's global footer rendering system.
/**
* Integration with ProLayout footer rendering
*/
interface ProLayoutFooterIntegration {
/** Custom footer renderer in ProLayout */
footerRender?: WithFalse<(props: any, defaultDom: React.ReactNode) => React.ReactNode>;
}Usage Example:
import React from "react";
import ProLayout, { DefaultFooter, FooterToolbar } from "@ant-design/pro-layout";
function LayoutWithFooter() {
return (
<ProLayout
title="My App"
footerRender={() => (
<DefaultFooter
copyright="© 2023 My Company"
links={[
{ key: 'about', title: 'About', href: '/about' },
{ key: 'contact', title: 'Contact', href: '/contact' },
]}
/>
)}
>
<div>Page content</div>
{/* Page-specific footer toolbar */}
<FooterToolbar>
<Button type="primary">Page Action</Button>
</FooterToolbar>
</ProLayout>
);
}<FooterToolbar
extra={<div>Changes are saved automatically</div>}
>
<Space>
<Button>Cancel</Button>
<Button type="primary" htmlType="submit">
Save
</Button>
</Space>
</FooterToolbar><FooterToolbar
extra={<div>Selected: {selectedCount} items</div>}
>
<Space>
<Button disabled={selectedCount === 0}>
Bulk Delete
</Button>
<Button disabled={selectedCount === 0}>
Bulk Export
</Button>
</Space>
</FooterToolbar><FooterToolbar>
<Space>
<Button disabled={currentStep === 0} onClick={prevStep}>
Previous
</Button>
<Button
type="primary"
onClick={currentStep === totalSteps - 1 ? handleFinish : nextStep}
>
{currentStep === totalSteps - 1 ? 'Finish' : 'Next'}
</Button>
</Space>
</FooterToolbar><DefaultFooter
copyright="© 2023 Company Name. All rights reserved."
links={[
{ key: 'privacy', title: 'Privacy Policy', href: '/privacy' },
{ key: 'terms', title: 'Terms of Service', href: '/terms' },
{ key: 'support', title: 'Support', href: '/support' },
{ key: 'api', title: 'API Docs', href: '/api-docs' },
]}
/>FooterToolbar automatically calculates its width based on:
FooterToolbar uses React Portal by default to render at the document root, ensuring:
Set portalDom={false} to render inline within the component tree when portal behavior is not desired.