Pagination performed by the backend.
| Order | Customer | Status | Total |
|---|---|---|---|
| #1042 | A. Whitfield | Shipped | £64.00 |
| #1041 | R. Okafor | Processing | £128.50 |
| #1040 | M. Iqbal | Shipped | £22.00 |
| #1039 | S. Novak | Refunded | £40.00 |
| #1038 | L. Duarte | Shipped | £96.20 |
| #1037 | P. Andersson | Processing | £15.75 |
<div class="ssp" data-page="1" style="--accent:#241430;">
<div class="ssp__scroll">
<table class="ssp__table">
<caption>Customer orders · 10 rows per page</caption>
<thead><tr><th scope="col">Order</th><th scope="col">Customer</th><th scope="col">Status</th><th scope="col">Total</th></tr></thead>
<tbody>
<tr data-row-page="1"><td>#1042</td><td>A. Whitfield</td><td>Shipped</td><td>£64.00</td></tr>
<tr data-row-page="1"><td>#1041</td><td>R. Okafor</td><td>Processing</td><td>£128.50</td></tr>
<tr data-row-page="2"><td>#1040</td><td>M. Iqbal</td><td>Shipped</td><td>£22.00</td></tr>
<tr data-row-page="2"><td>#1039</td><td>S. Novak</td><td>Refunded</td><td>£40.00</td></tr>
<tr data-row-page="3"><td>#1038</td><td>L. Duarte</td><td>Shipped</td><td>£96.20</td></tr>
<tr data-row-page="3"><td>#1037</td><td>P. Andersson</td><td>Processing</td><td>£15.75</td></tr>
</tbody>
</table>
</div>
<div class="ssp__footer">
<button type="button" class="ssp__nav" >← Prev</button>
<div class="ssp__pages" role="group" aria-label="Pages">
<button type="button" class="ssp__page ssp__page--1" aria-label="Page 1">1</button>
<button type="button" class="ssp__page ssp__page--2" aria-label="Page 2">2</button>
<button type="button" class="ssp__page ssp__page--3" aria-label="Page 3">3</button>
</div>
<button type="button" class="ssp__nav">Next </button>
</div>
</div>
<style>
.ssp { font: 14px system-ui, sans-serif; color: #241430; background: #FAF7F2; max-width: 480px; border: 1px solid #24143020; border-radius: 10px; overflow: hidden; }
.ssp__scroll { overflow-x: auto; }
.ssp__table { border-collapse: collapse; width: 100%; }
.ssp__table caption { text-align: left; font-weight: 600; padding: 10px 14px; }
.ssp__table th, .ssp__table td { padding: 10px 14px; text-align: left; border-bottom: 1px solid #24143020; white-space: nowrap; }
.ssp__table th { background: var(--accent); color: #FAF7F2; }
.ssp[data-page="1"] tbody tr:not([data-row-page="1"]) { display: none; }
.ssp[data-page="2"] tbody tr:not([data-row-page="2"]) { display: none; }
.ssp[data-page="3"] tbody tr:not([data-row-page="3"]) { display: none; }
.ssp__footer { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 10px 14px; border-top: 1px solid #24143020; }
.ssp__nav { font-size: 12px; border: 1px solid #24143040; background: #FAF7F2; border-radius: 6px; padding: 5px 10px; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; }
.ssp__nav:hover { background: #24143010; }
.ssp__pages { display: flex; gap: 4px; }
.ssp__page { width: 26px; height: 26px; border: 1px solid #24143040; background: #FAF7F2; border-radius: 6px; font: inherit; font-size: 12px; cursor: pointer; }
.ssp[data-page="1"] .ssp__page--1,
.ssp[data-page="2"] .ssp__page--2,
.ssp[data-page="3"] .ssp__page--3 { background: var(--accent); color: #FAF7F2; border-color: var(--accent); }
.ssp__spinner { width: 10px; height: 10px; border-radius: 50%; border: 2px solid #24143030; border-top-color: var(--accent); }
@keyframes ssp-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: no-preference) {
.ssp__spinner { animation: ssp-spin .2s linear infinite; }
}
.ssp--loading .ssp__scroll { opacity: .6; }
</style><div class="max-w-[480px] rounded-[10px] border border-[#24143020] font-sans text-sm text-[#241430] bg-[#FAF7F2] overflow-hidden" data-page="1" style="--accent:#241430;">
<div class="ssp__scroll overflow-x-auto">
<table class="border-collapse w-full">
<caption class="text-left font-semibold px-3.5 py-2.5">Customer orders · 10 rows per page</caption>
<thead><tr class="text-[#FAF7F2]" style="background:#241430">
<th scope="col" class="p-3.5 text-left whitespace-nowrap">Order</th>
<th scope="col" class="p-3.5 text-left whitespace-nowrap">Customer</th>
<th scope="col" class="p-3.5 text-left whitespace-nowrap">Status</th>
<th scope="col" class="p-3.5 text-left whitespace-nowrap">Total</th>
</tr></thead>
<tbody>
<tr data-row-page="1"><td class="p-3.5 border-b border-[#24143020] whitespace-nowrap">#1042</td><td class="p-3.5 border-b border-[#24143020] whitespace-nowrap">A. Whitfield</td><td class="p-3.5 border-b border-[#24143020] whitespace-nowrap">Shipped</td><td class="p-3.5 border-b border-[#24143020] whitespace-nowrap">£64.00</td></tr>
<tr data-row-page="1"><td class="p-3.5 border-b border-[#24143020] whitespace-nowrap">#1041</td><td class="p-3.5 border-b border-[#24143020] whitespace-nowrap">R. Okafor</td><td class="p-3.5 border-b border-[#24143020] whitespace-nowrap">Processing</td><td class="p-3.5 border-b border-[#24143020] whitespace-nowrap">£128.50</td></tr>
<tr data-row-page="2"><td class="p-3.5 border-b border-[#24143020] whitespace-nowrap">#1040</td><td class="p-3.5 border-b border-[#24143020] whitespace-nowrap">M. Iqbal</td><td class="p-3.5 border-b border-[#24143020] whitespace-nowrap">Shipped</td><td class="p-3.5 border-b border-[#24143020] whitespace-nowrap">£22.00</td></tr>
<tr data-row-page="2"><td class="p-3.5 border-b border-[#24143020] whitespace-nowrap">#1039</td><td class="p-3.5 border-b border-[#24143020] whitespace-nowrap">S. Novak</td><td class="p-3.5 border-b border-[#24143020] whitespace-nowrap">Refunded</td><td class="p-3.5 border-b border-[#24143020] whitespace-nowrap">£40.00</td></tr>
<tr data-row-page="3"><td class="p-3.5 border-b border-[#24143020] whitespace-nowrap">#1038</td><td class="p-3.5 border-b border-[#24143020] whitespace-nowrap">L. Duarte</td><td class="p-3.5 border-b border-[#24143020] whitespace-nowrap">Shipped</td><td class="p-3.5 border-b border-[#24143020] whitespace-nowrap">£96.20</td></tr>
<tr data-row-page="3"><td class="p-3.5 border-b border-[#24143020] whitespace-nowrap">#1037</td><td class="p-3.5 border-b border-[#24143020] whitespace-nowrap">P. Andersson</td><td class="p-3.5 border-b border-[#24143020] whitespace-nowrap">Processing</td><td class="p-3.5 border-b border-[#24143020] whitespace-nowrap">£15.75</td></tr>
</tbody>
</table>
</div>
<div class="flex items-center justify-between gap-2 px-3.5 py-2.5 border-t border-[#24143020]">
<button type="button" class="text-xs border border-[#24143040] bg-[#FAF7F2] rounded-md px-2.5 py-1">← Prev</button>
<div class="flex gap-1" role="group" aria-label="Pages">
<button type="button" class="ssp__page ssp__page--1 w-[26px] h-[26px] border border-[#24143040] bg-[#FAF7F2] rounded-md text-xs" aria-label="Page 1">1</button>
<button type="button" class="ssp__page ssp__page--2 w-[26px] h-[26px] border border-[#24143040] bg-[#FAF7F2] rounded-md text-xs" aria-label="Page 2">2</button>
<button type="button" class="ssp__page ssp__page--3 w-[26px] h-[26px] border border-[#24143040] bg-[#FAF7F2] rounded-md text-xs" aria-label="Page 3">3</button>
</div>
<button type="button" class="text-xs border border-[#24143040] bg-[#FAF7F2] rounded-md px-2.5 py-1 inline-flex items-center gap-1.5">Next </button>
</div>
</div>
<style>
[data-page="1"] tbody tr:not([data-row-page="1"]) { display: none; }
[data-page="2"] tbody tr:not([data-row-page="2"]) { display: none; }
[data-page="3"] tbody tr:not([data-row-page="3"]) { display: none; }
[data-page="1"] .ssp__page--1, [data-page="2"] .ssp__page--2, [data-page="3"] .ssp__page--3 { background: var(--accent); color: #FAF7F2; border-color: var(--accent); }
</style>function ServerSidePagination({
caption = "Customer orders",
accent = "#241430",
page = "1",
pageSize = "10",
loading = false,
}) {
const rows = [
["#1042", "A. Whitfield", "Shipped", "£64.00", "1"],
["#1041", "R. Okafor", "Processing", "£128.50", "1"],
["#1040", "M. Iqbal", "Shipped", "£22.00", "2"],
["#1039", "S. Novak", "Refunded", "£40.00", "2"],
["#1038", "L. Duarte", "Shipped", "£96.20", "3"],
["#1037", "P. Andersson", "Processing", "£15.75", "3"],
];
const visible = rows.filter((r) => r[4] === page);
const cell = { padding: "10px 14px", borderBottom: "1px solid #24143020", whiteSpace: "nowrap" };
return (
<div style={{ maxWidth: 480, borderRadius: 10, border: "1px solid #24143020", overflow: "hidden", font: "14px system-ui, sans-serif", color: "#241430", background: "#FAF7F2" }}>
<div style={{ overflowX: "auto", opacity: loading ? .6 : 1 }}>
<table style={{ borderCollapse: "collapse", width: "100%" }}>
<caption style={{ textAlign: "left", fontWeight: 600, padding: "10px 14px" }}>{caption} · {pageSize} rows per page</caption>
<thead>
<tr style={{ background: accent, color: "#FAF7F2" }}>
{["Order", "Customer", "Status", "Total"].map((h) => <th key={h} scope="col" style={cell}>{h}</th>)}
</tr>
</thead>
<tbody>
{visible.map((row) => (
<tr key={row[0]}>{row.slice(0, 4).map((c, j) => <td key={j} style={cell}>{c}</td>)}</tr>
))}
</tbody>
</table>
</div>
<div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8, padding: "10px 14px", borderTop: "1px solid #24143020" }}>
<button type="button" style={{ fontSize: 12, border: "1px solid #24143040", background: "#FAF7F2", borderRadius: 6, padding: "5px 10px", cursor: "pointer" }}>← Prev</button>
<div role="group" aria-label="Pages" style={{ display: "flex", gap: 4 }}>
{["1", "2", "3"].map((p) => (
<button key={p} type="button" aria-label={`Page ${p}`} style={{ width: 26, height: 26, border: `1px solid ${page === p ? accent : "#24143040"}`, background: page === p ? accent : "#FAF7F2", color: page === p ? "#FAF7F2" : "#241430", borderRadius: 6, fontSize: 12, cursor: "pointer" }}>{p}</button>
))}
</div>
<button type="button" style={{ fontSize: 12, border: "1px solid #24143040", background: "#FAF7F2", borderRadius: 6, padding: "5px 10px", cursor: "pointer", display: "inline-flex", alignItems: "center", gap: 6 }}>
Next {loading && <span aria-hidden="true" style={{ width: 10, height: 10, borderRadius: "50%", border: "2px solid #24143030", borderTopColor: accent }} />}
</button>
</div>
</div>
);
}