Page
A page scaffold with scroll restoration.
A page scaffold — the outer container for a screen, with scroll restoration handled by the engine.
Installation
npx touchcn add page
Usage
<tcn-page>
<tcn-navbar title="Home" />
<!-- page content -->
</tcn-page>import { TcnPage } from '@/components/ui/page';
import { TcnNavbar } from '@/components/ui/navbar';
<TcnPage>
<TcnNavbar title="Home" />
{/* page content */}
</TcnPage><script setup lang="ts">
import { TcnPage } from '@/components/ui/page';
import { TcnNavbar } from '@/components/ui/navbar';
</script>
<template>
<TcnPage>
<TcnNavbar title="Home" />
<!-- page content -->
</TcnPage>
</template>Props
TcnPage forwards all standard <div> attributes. Place a tcn-navbar and tcn-tabbar inside it near
the app root so their position: fixed chrome anchors to the viewport.
Source · Angular
export * from './tcn-page';import { Component, DestroyRef, ElementRef, inject } from '@angular/core';
import { TouchcnScrollRestoration } from '@touchcn/angular';
@Component({
selector: 'tcn-page',
template: '<ng-content />',
host: {
class:
'tcn-page tcn-safe-x relative block h-dvh overflow-y-auto bg-[var(--color-surface)] text-[var(--color-on-surface)]',
},
})
export class TcnPage {
private readonly scrollRestoration = inject(TouchcnScrollRestoration, { optional: true });
constructor() {
const element = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;
this.scrollRestoration?.register(element);
inject(DestroyRef).onDestroy(() => this.scrollRestoration?.unregister(element));
}
}Source · React
export * from './tcn-page';import { forwardRef } from 'react';
import type { ComponentPropsWithoutRef } from 'react';
import { cn } from '@touchcn/core';
export type TcnPageProps = ComponentPropsWithoutRef<'div'>;
/**
* Full-height, scrollable screen container. It fills the dynamic viewport
* (`h-dvh`), owns the vertical scroll, and applies the horizontal safe-area
* insets so content never sits under a notch.
*/
export const TcnPage = forwardRef<HTMLDivElement, TcnPageProps>(function TcnPage({ className, children, ...props }, ref) {
return (
<div
ref={ref}
className={cn(
'tcn-page tcn-safe-x relative block h-dvh overflow-y-auto bg-[var(--color-surface)] text-[var(--color-on-surface)]',
className,
)}
{...props}
>
{children}
</div>
);
});Source · Vue
<template>
<div
class="tcn-page tcn-safe-x relative block h-dvh overflow-y-auto bg-[var(--color-surface)] text-[var(--color-on-surface)]"
>
<slot />
</div>
</template>export { default as TcnPage } from './TcnPage.vue';