Skip to content
LuoForge/Tungsten
← All recipes

Paged list navigation

A default Pagination wired to local state — the windowed page list with first/last anchors and ellipsis collapses gracefully as the page count grows.

Preview

  • Item 1
  • Item 2
  • Item 3
  • Item 4
  • Item 5

Source

apps/docs/app/recipes/pagination-basic/recipe.tsx
'use client';

import { useState } from 'react';
import { Pagination } from '@hey-mike/tungsten';

const ALL_ITEMS = Array.from({ length: 47 }, (_, i) => `Item ${i + 1}`);
const PAGE_SIZE = 5;

export default function PaginationBasicRecipe() {
  const [page, setPage] = useState(1);
  const totalPages = Math.ceil(ALL_ITEMS.length / PAGE_SIZE);
  const start = (page - 1) * PAGE_SIZE;
  const visible = ALL_ITEMS.slice(start, start + PAGE_SIZE);

  return (
    <div className="flex flex-col items-center gap-4">
      <ul className="text-ink-1 w-48 space-y-1 text-sm">
        {visible.map((item) => (
          <li key={item} className="bg-surface-2 rounded-input-inner px-3 py-1.5">
            {item}
          </li>
        ))}
      </ul>
      <Pagination totalPages={totalPages} page={page} onPageChange={setPage} />
    </div>
  );
}
'use client';

import { useState } from 'react';
import { Pagination } from '@hey-mike/tungsten';

const ALL_ITEMS = Array.from({ length: 47 }, (_, i) => `Item ${i + 1}`);
const PAGE_SIZE = 5;

export default function PaginationBasicRecipe() {
  const [page, setPage] = useState(1);
  const totalPages = Math.ceil(ALL_ITEMS.length / PAGE_SIZE);
  const start = (page - 1) * PAGE_SIZE;
  const visible = ALL_ITEMS.slice(start, start + PAGE_SIZE);

  return (
    <div className="flex flex-col items-center gap-4">
      <ul className="text-ink-1 w-48 space-y-1 text-sm">
        {visible.map((item) => (
          <li key={item} className="bg-surface-2 rounded-input-inner px-3 py-1.5">
            {item}
          </li>
        ))}
      </ul>
      <Pagination totalPages={totalPages} page={page} onPageChange={setPage} />
    </div>
  );
}