● Zion Boggan
repos/Docket/components/show-more.tsx
zionboggan.com ↗
47 lines · tsx
History for this file →
1
"use client";
2
 
3
import { useState, type ReactNode } from "react";
4
 
5
 
6
export function ShowMore({
7
  items,
8
  pageSize = 50,
9
  controlWrapper = "div",
10
  noun = "more",
11
}: {
12
  items: ReactNode[];
13
  pageSize?: number;
14
  controlWrapper?: "div" | "li";
15
  noun?: string;
16
}) {
17
  const [shown, setShown] = useState(pageSize);
18
  const visible = items.slice(0, shown);
19
  const remaining = items.length - shown;
20
 
21
  const control =
22
    remaining > 0 ? (
23
      <div className="flex items-center justify-between gap-3 px-4 py-3">
24
        <span className="label text-ash-2">
25
          Showing {shown.toLocaleString()} of {items.length.toLocaleString()}
26
        </span>
27
        <button
28
          type="button"
29
          onClick={() => setShown((n) => n + pageSize)}
30
          className="focus-ring label inline-flex min-h-[40px] items-center rounded-[3px] border border-line px-3 text-ash underline underline-offset-4 transition-colors hover:border-paper hover:text-paper"
31
        >
32
          Show {Math.min(pageSize, remaining).toLocaleString()} {noun}
33
        </button>
34
      </div>
35
    ) : null;
36
 
37
  return (
38
    <>
39
      {visible}
40
      {control
41
        ? controlWrapper === "li"
42
          ? <li>{control}</li>
43
          : control
44
        : null}
45
    </>
46
  );
47
}