Files
medusa-store/www/apps/resources/app/admin-components/components/table/page.mdx
Shahed Nasser 74b286b701 docs: added documentation for admin components (#9491)
- Documented common admin components with design that matches the admin.
- Updated existing admin customization snippets to match the admin's design.

Closes DOCS-964
2024-10-14 07:18:38 +00:00

246 lines
6.3 KiB
Plaintext

---
sidebar_label: "Table"
---
import { TypeList } from "docs-ui"
export const metadata = {
title: `Table - Admin Components`,
}
# {metadata.title}
The listing pages in the Admin show a table with pagination.
![Example of a table in the product listing page](https://res.cloudinary.com/dza7lstvk/image/upload/v1728295658/Medusa%20Resources/list_ddt9zc.png)
To create a component that shows a table with pagination, create the file `src/admin/components/table.tsx` with the following content:
```tsx title="src/admin/components/table.tsx"
import { useMemo } from "react"
import { Table as UiTable } from "@medusajs/ui"
export type TableProps = {
columns: {
key: string
label?: string
render?: (value: unknown) => React.ReactNode
}[]
data: Record<string, unknown>[]
pageSize: number
count: number
currentPage: number
setCurrentPage: (value: number) => void
}
export const Table = ({
columns,
data,
pageSize,
count,
currentPage,
setCurrentPage
}: TableProps) => {
const pageCount = useMemo(() => {
return Math.ceil(data.length / pageSize)
}, [data, pageSize])
const canNextPage = useMemo(() => {
return currentPage < pageCount - 1
}, [currentPage, pageCount])
const canPreviousPage = useMemo(() => {
return currentPage - 1 >= 0
}, [currentPage])
const nextPage = () => {
if (canNextPage) {
setCurrentPage(currentPage + 1)
}
}
const previousPage = () => {
if (canPreviousPage) {
setCurrentPage(currentPage - 1)
}
}
return (
<div className="flex h-full flex-col overflow-hidden !border-t-0">
<UiTable>
<UiTable.Header>
<UiTable.Row>
{columns.map((column, index) => (
<UiTable.HeaderCell key={index}>
{column.label || column.key}
</UiTable.HeaderCell>
))}
</UiTable.Row>
</UiTable.Header>
<UiTable.Body>
{data.map((item, index) => {
const rowIndex = "id" in item ? item.id as string : index
return (
<UiTable.Row key={rowIndex}>
{columns.map((column, index) => (
<UiTable.Cell key={`${rowIndex}-${index}`}>
<>
{column.render && column.render(item[column.key])}
{!column.render && (
<>{item[column.key] as string}</>
)}
</>
</UiTable.Cell>
))}
</UiTable.Row>
)
})}
</UiTable.Body>
</UiTable>
<UiTable.Pagination
count={count}
pageSize={pageSize}
pageIndex={currentPage}
pageCount={pageCount}
canPreviousPage={canPreviousPage}
canNextPage={canNextPage}
previousPage={previousPage}
nextPage={nextPage}
/>
</div>
)
}
```
The `Table` component uses the component from the [UI package](!ui!/components/table), with additional styling and rendering of data.
It accepts the following props:
<TypeList
types={[
{
name: "columns",
type: "`object[]`",
optional: false,
description: "The table's columns.",
children: [
{
name: "key",
type: "`string`",
optional: false,
description: "The column's key in the passed `data`"
},
{
name: "label",
type: "`string`",
optional: true,
description: "The column's label shown in the table. If not provided, the `key` is used."
},
{
name: "render",
type: "`(value: unknown) => React.ReactNode`",
optional: true,
description: "By default, the data is shown as-is in the table. You can use this function to change how the value is rendered. The function receives the value is a parameter and returns a React node."
}
]
},
{
name: "data",
type: "`Record<string, unknown>[]`",
optional: false,
description: "The data to show in the table for the current page. The keys of each object should be in the `columns` array."
},
{
name: "pageSize",
type: "`number`",
optional: false,
description: "The number of items to show per page."
},
{
name: "count",
type: "`number`",
optional: false,
description: "The total number of items."
},
{
name: "currentPage",
type: "`number`",
optional: false,
description: "A zero-based index indicating the current page's number."
},
{
name: "setCurrentPage",
type: "`(value: number) => void`",
optional: false,
description: "A function used to change the current page."
}
]}
/>
---
## Example
Use the `Table` component in any widget or UI route.
For example, create the widget `src/admin/widgets/product-widget.tsx` with the following content:
```tsx title="src/admin/widgets/product-widget.tsx"
import { defineWidgetConfig } from "@medusajs/admin-sdk"
import { StatusBadge } from "@medusajs/ui"
import { Table } from "../components/table"
import { useState } from "react"
import { Container } from "../components/container"
const ProductWidget = () => {
const [currentPage, setCurrentPage] = useState(0)
return (
<Container>
<Table
columns={[
{
key: "name",
label: "Name"
},
{
key: "is_enabled",
label: "Status",
render: (value: unknown) => {
const isEnabled = value as boolean
return (
<StatusBadge color={isEnabled ? "green" : "grey"}>
{isEnabled ? "Enabled" : "Disabled"}
</StatusBadge>
)
}
}
]}
data={[
{
name: "John",
is_enabled: true
},
{
name: "Jane",
is_enabled: false
}
]}
pageSize={2}
count={2}
currentPage={currentPage}
setCurrentPage={setCurrentPage}
/>
</Container>
)
}
export const config = defineWidgetConfig({
zone: "product.details.before",
})
export default ProductWidget
```
This widget also uses the [Container](../container.mdx) custom component.