Skip to main content

Page

The primary container for business pages. Supports left/right aside panels, header, footer, action bar, and scrollable content.

VEF-specific component. Not part of Ant Design. Moved from @vef-framework-react/starter to @vef-framework-react/components in v2.1.6.

When to Use

  • Any standard business page that needs a consistent layout shell.
  • Pages with a left-side tree and right-side content area.
  • Pages that need a sticky header or footer.

Basic Usage

import { Page } from '@vef-framework-react/components';

export default function UserPage() {
return (
<Page>
<div>Main content</div>
</Page>
);
}

With Left Aside

import { Page } from '@vef-framework-react/components';

export default function UserPage() {
return (
<Page
leftAside={<DeptTree />}
leftAsideWidth={260}
>
<UserTable />
</Page>
);
}

Resizable Aside

<Page
leftAside={<DeptTree />}
leftAsideWidth={{ defaultWidth: 260, minWidth: 180, maxWidth: 400 }}
>
<UserTable />
</Page>
<Page
header={<PageTitle>Users</PageTitle>}
headerPosition="outside"
footer={<StatusBar />}
footerPosition="inside"
>
<UserTable />
</Page>

API

PropTypeDefaultDescription
classNamestringClass name for the page container
marginbooleanfalseApply var(--vef-spacing-md) margin to the container
gapLengthvar(--vef-spacing-md)Gap between grid cells
mainClassNamestringClass name for the main content area
leftAsideReactNodeLeft aside content
leftAsideClassNamestringClass name for the left aside
leftAsideWidthAsideWidth280Fixed width or resizable config
rightAsideReactNodeRight aside content
rightAsideClassNamestringClass name for the right aside
rightAsideWidthAsideWidth280Fixed width or resizable config
headerReactNodeHeader content
headerClassNamestringClass name for the header
headerPosition'inside' | 'outside''inside''outside' spans full width including asides
footerReactNodeFooter content
footerClassNamestringClass name for the footer
footerPosition'inside' | 'outside''inside''outside' spans full width including asides
actionBarReactNodeAction bar content
actionBarClassNamestringClass name for the action bar
scrollablebooleanWhether main content is scrollable
scrollMarginbooleanfalseAuto margin for scrollbar spacing (requires scrollable)

AsideWidth

type AsideWidth = string | number | {
defaultWidth?: string | number;
minWidth?: string | number;
maxWidth?: string | number;
};

useViewportHeight

A hook exported alongside Page for calculating available viewport height:

import { useViewportHeight } from '@vef-framework-react/components';

const height = useViewportHeight();

useViewportHeight throws if called outside a <Page scrollable> — it reads a context value that only Page provides, and only when scrollable is true.

Entrance Hooks

Page plays an entrance animation on mount and exposes "the page has finished arriving" as a signal. Secondary motion, auto-focus, guided hints, or deferred heavy initialization can key off it so they start after the entrance instead of competing with it:

ExportTypeDescription
usePageEntranceEffect(effect: () => void | (() => void)) => voidRuns effect once the hosting Page's entrance has settled — immediately when already settled (including outside a Page). Causes zero re-renders. The cleanup runs on unmount, and the effect re-arms if a page reload replays the entrance
usePageEntranceSettled() => booleanWhether the entrance has finished (immediately true outside a Page). Subscribes the component — it re-renders once when the entrance settles. Use when the settled state drives rendering
PageEntranceStore{ isSettled(): boolean; subscribe(listener): () => void }The underlying store type carried by the context

CSS can also target the Page root's data-entrance attribute directly.

usePageEntranceEffect(() => {
chart.startEntranceSequence();
});