Paginated Table
cinatra-ai/paginated-tableFreeComponent
Cinatra design-system table-with-pagination composite.
Live preview
live · rendered by the registry
Rendered by @cinatra-ai on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://raw.githubusercontent.com/cinatra-ai/cinatra/main/public/r/paginated-table.jsonSource
1"use client"23import * as React from "react"45import {6 Pagination,7 PaginationContent,8 PaginationItem,9 PaginationNext,10 PaginationPrevious,11} from "@/components/ui/pagination"12import { Table } from "@/components/ui/table"13import { cn } from "@/lib/utils"1415const DEFAULT_TABLE_PAGE_SIZE = 251617type PaginatedTableProps = React.ComponentProps<typeof Table> & {18 pageSize?: number19 pagination?: boolean20}2122function getTableBodyRows(frame: HTMLDivElement | null): HTMLTableRowElement[] {23 const table = frame?.querySelector("table")2425 if (!table) {26 return []27 }2829 return Array.from(table.tBodies).flatMap((body) => Array.from(body.rows))30}3132function PaginatedTable({33 className,34 children,35 id,36 pageSize = DEFAULT_TABLE_PAGE_SIZE,37 pagination = true,38 ...props39}: PaginatedTableProps) {40 const generatedTableId = React.useId()41 const tableId = id ?? generatedTableId42 const frameRef = React.useRef<HTMLDivElement>(null)43 const [rowCount, setRowCount] = React.useState(0)44 const [pageIndex, setPageIndex] = React.useState(0)45 const safePageSize = Number.isFinite(pageSize) && pageSize > 046 ? pageSize47 : DEFAULT_TABLE_PAGE_SIZE48 const shouldPaginate = pagination && rowCount > safePageSize49 const pageCount = shouldPaginate ? Math.ceil(rowCount / safePageSize) : 150 const safePageIndex = shouldPaginate51 ? Math.min(pageIndex, Math.max(0, pageCount - 1))52 : 053 const firstRow = shouldPaginate ? safePageIndex * safePageSize + 1 : 154 const lastRow = shouldPaginate55 ? Math.min(rowCount, (safePageIndex + 1) * safePageSize)56 : rowCount57 const isFirstPage = safePageIndex === 058 const isLastPage = safePageIndex >= pageCount - 15960 const refreshRowCount = React.useCallback(() => {61 setRowCount(getTableBodyRows(frameRef.current).length)62 }, [])6364 React.useEffect(() => {65 refreshRowCount()6667 const frame = frameRef.current68 if (!frame || typeof MutationObserver === "undefined") {69 return70 }7172 const observer = new MutationObserver(refreshRowCount)73 observer.observe(frame, { childList: true, subtree: true })7475 return () => observer.disconnect()76 }, [children, refreshRowCount])7778 React.useEffect(() => {79 setPageIndex((current) => Math.min(current, Math.max(0, pageCount - 1)))80 }, [pageCount])8182 React.useEffect(() => {83 const frame = frameRef.current84 const rows = getTableBodyRows(frame)85 const firstVisibleRow = safePageIndex * safePageSize86 const lastVisibleRow = firstVisibleRow + safePageSize8788// … truncated
What it pulls in
Other registry items
Files it writes
More from @cinatra-ai
All 14 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Alertalert | @cinatra-ai | Components | Free | 1 dep | |
| Badgebadge | @cinatra-ai | Components | Free | 2 deps | |
| Buttonbutton | @cinatra-ai | Components | Free | 2 deps | |
| Cardcard | @cinatra-ai | Components | Free | no deps | |
| Fieldfield | @cinatra-ai | Components | Free | 1 dep | |
| Inputinput | @cinatra-ai | Components | Free | no deps | |
| Input Groupinput-group | @cinatra-ai | Components | Free | 1 dep | |
| Labellabel | @cinatra-ai | Components | Free | 1 dep |
