const data = `const columns = [ {name: "ID", uid: "id", sortable: true}, {name: "NAME", uid: "name", sortable: true}, {name: "AGE", uid: "age", sortable: true}, {name: "ROLE", uid: "role", sortable: true}, {name: "TEAM", uid: "team"}, {name: "EMAIL", uid: "email"}, {name: "STATUS", uid: "status", sortable: true}, {name: "ACTIONS", uid: "actions"}, ]; const statusOptions = [ {name: "Active", uid: "active"}, {name: "Paused", uid: "paused"}, {name: "Vacation", uid: "vacation"}, ]; const users = [ { id: 1, name: "Tony Reichert", role: "CEO", team: "Management", status: "active", age: "29", avatar: "https://i.pravatar.cc/150?u=a042581f4e29026024d", email: "tony.reichert@example.com", }, { id: 2, name: "Zoey Lang", role: "Tech Lead", team: "Development", status: "paused", age: "25", avatar: "https://i.pravatar.cc/150?u=a042581f4e29026704d", email: "zoey.lang@example.com", }, { id: 3, name: "Jane Fisher", role: "Sr. Dev", team: "Development", status: "active", age: "22", avatar: "https://i.pravatar.cc/150?u=a04258114e29026702d", email: "jane.fisher@example.com", }, { id: 4, name: "William Howard", role: "C.M.", team: "Marketing", status: "vacation", age: "28", avatar: "https://i.pravatar.cc/150?u=a048581f4e29026701d", email: "william.howard@example.com", }, { id: 5, name: "Kristen Copper", role: "S. Manager", team: "Sales", status: "active", age: "24", avatar: "https://i.pravatar.cc/150?u=a092581d4ef9026700d", email: "kristen.cooper@example.com", }, { id: 6, name: "Brian Kim", role: "P. Manager", team: "Management", age: "29", avatar: "https://i.pravatar.cc/150?u=a042581f4e29026024d", email: "brian.kim@example.com", status: "Active", }, { id: 7, name: "Michael Hunt", role: "Designer", team: "Design", status: "paused", age: "27", avatar: "https://i.pravatar.cc/150?u=a042581f4e29027007d", email: "michael.hunt@example.com", }, { id: 8, name: "Samantha Brooks", role: "HR Manager", team: "HR", status: "active", age: "31", avatar: "https://i.pravatar.cc/150?u=a042581f4e27027008d", email: "samantha.brooks@example.com", }, { id: 9, name: "Frank Harrison", role: "F. Manager", team: "Finance", status: "vacation", age: "33", avatar: "https://i.pravatar.cc/150?img=4", email: "frank.harrison@example.com", }, { id: 10, name: "Emma Adams", role: "Ops Manager", team: "Operations", status: "active", age: "35", avatar: "https://i.pravatar.cc/150?img=5", email: "emma.adams@example.com", }, { id: 11, name: "Brandon Stevens", role: "Jr. Dev", team: "Development", status: "active", age: "22", avatar: "https://i.pravatar.cc/150?img=8", email: "brandon.stevens@example.com", }, { id: 12, name: "Megan Richards", role: "P. Manager", team: "Product", status: "paused", age: "28", avatar: "https://i.pravatar.cc/150?img=10", email: "megan.richards@example.com", }, { id: 13, name: "Oliver Scott", role: "S. Manager", team: "Security", status: "active", age: "37", avatar: "https://i.pravatar.cc/150?img=12", email: "oliver.scott@example.com", }, { id: 14, name: "Grace Allen", role: "M. Specialist", team: "Marketing", status: "active", age: "30", avatar: "https://i.pravatar.cc/150?img=16", email: "grace.allen@example.com", }, { id: 15, name: "Noah Carter", role: "IT Specialist", team: "I. Technology", status: "paused", age: "31", avatar: "https://i.pravatar.cc/150?img=15", email: "noah.carter@example.com", }, { id: 16, name: "Ava Perez", role: "Manager", team: "Sales", status: "active", age: "29", avatar: "https://i.pravatar.cc/150?img=20", email: "ava.perez@example.com", }, { id: 17, name: "Liam Johnson", role: "Data Analyst", team: "Analysis", status: "active", age: "28", avatar: "https://i.pravatar.cc/150?img=33", email: "liam.johnson@example.com", }, { id: 18, name: "Sophia Taylor", role: "QA Analyst", team: "Testing", status: "active", age: "27", avatar: "https://i.pravatar.cc/150?img=29", email: "sophia.taylor@example.com", }, { id: 19, name: "Lucas Harris", role: "Administrator", team: "Information Technology", status: "paused", age: "32", avatar: "https://i.pravatar.cc/150?img=50", email: "lucas.harris@example.com", }, { id: 20, name: "Mia Robinson", role: "Coordinator", team: "Operations", status: "active", age: "26", avatar: "https://i.pravatar.cc/150?img=45", email: "mia.robinson@example.com", }, ]; export {columns, users, statusOptions};`; const utils = `export function capitalize(str) { return str.charAt(0).toUpperCase() + str.slice(1); }`; const PlusIcon = `export const PlusIcon = ({size = 24, width, height, ...props}) => ( );`; const VerticalDotsIcon = `export const VerticalDotsIcon = ({size = 24, width, height, ...props}) => ( );`; const SearchIcon = `export const SearchIcon = (props) => ( );`; const ChevronDownIcon = `export const ChevronDownIcon = ({strokeWidth = 1.5, ...otherProps}) => ( );`; const App = `import { Table, TableHeader, TableColumn, TableBody, TableRow, TableCell, Input, Button, DropdownTrigger, Dropdown, DropdownMenu, DropdownItem, Chip, User, Pagination, } from "@nextui-org/react"; import {PlusIcon} from "./PlusIcon"; import {VerticalDotsIcon} from "./VerticalDotsIcon"; import {SearchIcon} from "./SearchIcon"; import {ChevronDownIcon} from "./ChevronDownIcon"; import {columns, users, statusOptions} from "./data"; import {capitalize} from "./utils"; const statusColorMap = { active: "success", paused: "danger", vacation: "warning", }; const INITIAL_VISIBLE_COLUMNS = ["name", "role", "status", "actions"]; export default function App() { const [filterValue, setFilterValue] = React.useState(""); const [selectedKeys, setSelectedKeys] = React.useState(new Set([])); const [visibleColumns, setVisibleColumns] = React.useState(new Set(INITIAL_VISIBLE_COLUMNS)); const [statusFilter, setStatusFilter] = React.useState("all"); const [rowsPerPage, setRowsPerPage] = React.useState(5); const [sortDescriptor, setSortDescriptor] = React.useState({ column: "age", direction: "ascending", }); const [page, setPage] = React.useState(1); const hasSearchFilter = Boolean(filterValue); const headerColumns = React.useMemo(() => { if (visibleColumns === "all") return columns; return columns.filter((column) => Array.from(visibleColumns).includes(column.uid)); }, [visibleColumns]); const filteredItems = React.useMemo(() => { let filteredUsers = [...users]; if (hasSearchFilter) { filteredUsers = filteredUsers.filter((user) => user.name.toLowerCase().includes(filterValue.toLowerCase()), ); } if (statusFilter !== "all" && Array.from(statusFilter).length !== statusOptions.length) { filteredUsers = filteredUsers.filter((user) => Array.from(statusFilter).includes(user.status), ); } return filteredUsers; }, [users, filterValue, statusFilter]); const pages = Math.ceil(filteredItems.length / rowsPerPage); const items = React.useMemo(() => { const start = (page - 1) * rowsPerPage; const end = start + rowsPerPage; return filteredItems.slice(start, end); }, [page, filteredItems, rowsPerPage]); const sortedItems = React.useMemo(() => { return [...items].sort((a, b) => { const first = a[sortDescriptor.column]; const second = b[sortDescriptor.column]; const cmp = first < second ? -1 : first > second ? 1 : 0; return sortDescriptor.direction === "descending" ? -cmp : cmp; }); }, [sortDescriptor, items]); const renderCell = React.useCallback((user, columnKey) => { const cellValue = user[columnKey]; switch (columnKey) { case "name": return ( {user.email} ); case "role": return (

{cellValue}

{user.team}

); case "status": return ( {cellValue} ); case "actions": return (
View Edit Delete
); default: return cellValue; } }, []); const onNextPage = React.useCallback(() => { if (page < pages) { setPage(page + 1); } }, [page, pages]); const onPreviousPage = React.useCallback(() => { if (page > 1) { setPage(page - 1); } }, [page]); const onRowsPerPageChange = React.useCallback((e) => { setRowsPerPage(Number(e.target.value)); setPage(1); }, []); const onSearchChange = React.useCallback((value) => { if (value) { setFilterValue(value); setPage(1); } else { setFilterValue(""); } }, []); const onClear = useCallback(()=>{ setFilterValue("") setPage(1) },[]) const topContent = React.useMemo(() => { return (
} value={filterValue} onClear={() => onClear()} onValueChange={onSearchChange} />
{statusOptions.map((status) => ( {capitalize(status.name)} ))} {columns.map((column) => ( {capitalize(column.name)} ))}
Total {users.length} users
); }, [ filterValue, statusFilter, visibleColumns, onRowsPerPageChange, users.length, onSearchChange, hasSearchFilter, ]); const bottomContent = React.useMemo(() => { return (
{selectedKeys === "all" ? "All items selected" : \`\${selectedKeys.size} of \${filteredItems.length} selected\`}
); }, [selectedKeys, items.length, page, pages, hasSearchFilter]); return ( {(column) => ( {column.name} )} {(item) => ( {(columnKey) => {renderCell(item, columnKey)}} )}
); }`; const AppTs = `import { Table, TableHeader, TableColumn, TableBody, TableRow, TableCell, Input, Button, DropdownTrigger, Dropdown, DropdownMenu, DropdownItem, Chip, User, Pagination, Selection, ChipProps, SortDescriptor } from "@nextui-org/react"; import {PlusIcon} from "./PlusIcon"; import {VerticalDotsIcon} from "./VerticalDotsIcon"; import {ChevronDownIcon} from "./ChevronDownIcon"; import {SearchIcon} from "./SearchIcon"; import {columns, users, statusOptions} from "./data"; import {capitalize} from "./utils"; const statusColorMap: Record = { active: "success", paused: "danger", vacation: "warning", }; const INITIAL_VISIBLE_COLUMNS = ["name", "role", "status", "actions"]; type User = typeof users[0]; export default function App() { const [filterValue, setFilterValue] = React.useState(""); const [selectedKeys, setSelectedKeys] = React.useState(new Set([])); const [visibleColumns, setVisibleColumns] = React.useState(new Set(INITIAL_VISIBLE_COLUMNS)); const [statusFilter, setStatusFilter] = React.useState("all"); const [rowsPerPage, setRowsPerPage] = React.useState(5); const [sortDescriptor, setSortDescriptor] = React.useState({ column: "age", direction: "ascending", }); const [page, setPage] = useState(1); const hasSearchFilter = Boolean(filterValue); const headerColumns = React.useMemo(() => { if (visibleColumns === "all") return columns; return columns.filter((column) => Array.from(visibleColumns).includes(column.uid)); }, [visibleColumns]); const filteredItems = React.useMemo(() => { let filteredUsers = [...users]; if (hasSearchFilter) { filteredUsers = filteredUsers.filter((user) => user.name.toLowerCase().includes(filterValue.toLowerCase()), ); } if (statusFilter !== "all" && Array.from(statusFilter).length !== statusOptions.length) { filteredUsers = filteredUsers.filter((user) => Array.from(statusFilter).includes(user.status), ); } return filteredUsers; }, [users, filterValue, statusFilter]); const pages = Math.ceil(filteredItems.length / rowsPerPage); const items = React.useMemo(() => { const start = (page - 1) * rowsPerPage; const end = start + rowsPerPage; return filteredItems.slice(start, end); }, [page, filteredItems, rowsPerPage]); const sortedItems = React.useMemo(() => { return [...items].sort((a: User, b: User) => { const first = a[sortDescriptor.column as keyof User] as number; const second = b[sortDescriptor.column as keyof User] as number; const cmp = first < second ? -1 : first > second ? 1 : 0; return sortDescriptor.direction === "descending" ? -cmp : cmp; }); }, [sortDescriptor, items]); const renderCell = React.useCallback((user: User, columnKey: React.Key) => { const cellValue = user[columnKey]; switch (columnKey) { case "name": return ( {user.email} ); case "role": return (

{cellValue}

{user.team}

); case "status": return ( {cellValue} ); case "actions": return (
View Edit Delete
); default: return cellValue; } }, []); const onNextPage = React.useCallback(() => { if (page < pages) { setPage(page + 1); } }, [page, pages]); const onPreviousPage = React.useCallback(() => { if (page > 1) { setPage(page - 1); } }, [page]); const onRowsPerPageChange = React.useCallback((e: React.ChangeEvent) => { setRowsPerPage(Number(e.target.value)); setPage(1); }, []); const onSearchChange = React.useCallback((value?: string) => { if (value) { setFilterValue(value); setPage(1); } else { setFilterValue(""); } }, []); const onClear = useCallback(()=>{ setFilterValue("") setPage(1) },[]) const topContent = React.useMemo(() => { return (
} value={filterValue} onClear={() => onClear()} onValueChange={onSearchChange} />
{statusOptions.map((status) => ( {capitalize(status.name)} ))} {columns.map((column) => ( {capitalize(column.name)} ))}
Total {users.length} users
); }, [ filterValue, statusFilter, visibleColumns, onSearchChange, onRowsPerPageChange, users.length, hasSearchFilter, ]); const bottomContent = React.useMemo(() => { return (
{selectedKeys === "all" ? "All items selected" : \`\${selectedKeys.size} of \${filteredItems.length} selected\`}
); }, [selectedKeys, items.length, page, pages, hasSearchFilter]); return ( {(column) => ( {column.name} )} {(item) => ( {(columnKey) => {renderCell(item, columnKey)}} )}
); }`; const react = { "/App.jsx": App, "/data.js": data, "/utils.js": utils, "/PlusIcon.jsx": PlusIcon, "/VerticalDotsIcon.jsx": VerticalDotsIcon, "/SearchIcon.jsx": SearchIcon, "/ChevronDownIcon.jsx": ChevronDownIcon, }; const reactTs = { "/App.tsx": AppTs, }; export default { ...react, ...reactTs, };