UNPKG

glide-design-system

Version:

Glide design system is an open-source React component library. It offers numerous benefits that make them essential tools for design and development teams.

361 lines (352 loc) 12.1 kB
import React from "react"; import "./table.css"; import { Chip } from "../chip/Chip"; import { ProgressCircle } from "../loader/ProgressCircle"; export const Table = ({ columns, data, sortHandler, sortItem, sortOrder, tableRowStyles, tableHeaderStyle, linkHandler, actionHandler, style, loading, chipStyle, progressCircleStyle, progressCircleClass, progressCircleContainerClass, message, tableContainerStyle, containerClass, id, name, key, noDataStyle, }) => { const columnWidth = `${100 / columns.length}%`; const camelCaseToWords = (word) => { return word .replace(/([A-Z])/g, " $1") // Insert a space before each capital letter .trim() // Remove any leading/trailing spaces .toUpperCase(); // Convert the whole string to uppercase }; const formatTimestampToDateString = (timestamp) => { const dateObj = new Date(timestamp); const monthNames = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", ]; const month = monthNames[dateObj.getMonth()]; const day = dateObj.getDate(); const year = dateObj.getFullYear(); return `${month} ${day} ${year}`; }; const renderChip = (data, column) => { if (column?.type === "chip") { const statusValue = data?.[column?.fieldName ? column?.fieldName : column?.label]; const chipProperties = column?.chipOptions?.filter((chipvalue) => { return chipvalue?.value === statusValue; }); const { value, ...chipStyles } = chipProperties?.[0]; return <Chip style={{ ...chipStyle, ...chipStyles }}>{statusValue}</Chip>; } }; const combinedStyle = { ...style, }; return ( <div style={{ overflowX: "auto", overflowY: "hidden", ...tableContainerStyle }} className={containerClass ? containerClass : ""} > <table style={combinedStyle} className="table" data-testid={id} id={id} name={name} > <thead style={{ borderBottom: "1px solid #d7d7d7" }}> <tr className="tr" style={{ height: 40, backgroundColor: "#f9f9f9", borderBottom: "1px solid #d7d7d7", ...tableHeaderStyle, }} > {columns.map((column, index) => { return ( <th key={column?.fieldName ? column?.fieldName : column?.label} id={column?.fieldName ? column?.fieldName : column?.label} style={{ width: column?.style?.width || columnWidth, textAlign: "left", borderRight: index !== columns.length - 1 ? "1px solid #d7d7d7" : "none", color: "#7f7f7f", fontSize: "12px", fontWeight: "700", fontFamily: "Roboto, sans-serif", paddingLeft: "12.5px", ...column?.style, }} > <div style={{ display: "flex", alignItems: "center" }}> <p fontWeight="bold" fontSize={12} //style={styles.tableHeader} > {camelCaseToWords(column?.label)} </p> {column?.sort && ( <div data-testid={`${ column?.fieldName ? column?.fieldName : column?.label }SortIcon`} id={`${ column?.fieldName ? column?.fieldName : column?.label }SortIcon`} className="sortIcon" style={{ paddingLeft: "5px" }} onClick={() => { sortHandler && sortHandler( sortOrder === "asc" ? "desc" : "asc", column?.fieldName ? column?.fieldName : column?.label ); }} > {sortItem === (column?.fieldName ? column?.fieldName : column?.label) ? ( sortOrder === "desc" ? ( <span style={{ color: "#7f7f7f", }} className="material-symbols-outlined" > expand_more </span> ) : ( <span style={{ color: "#7f7f7f", }} className="material-symbols-outlined" > expand_less </span> ) ) : ( <span style={{ color: "#7f7f7f", writingMode: "vertical-lr", direction: "rtl", fontSize: "18px", }} className="material-symbols-outlined" > code </span> )} </div> )} </div> </th> ); })} </tr> </thead> <tbody> {loading ? ( <tr style={{ height: 40, fontFamily: "Roboto, sans-serif", fontSize: "14px", ...tableRowStyles, }} > {columns.map((column, index) => { return ( <td key={`loader-${index + 1}-${key ? key : ""}`} style={{ justifyContent: "center", alignItems: "center", width: columnWidth, paddingInline: "6px", ...column?.style, }} > {index === Math.floor(columns.length / 2) ? ( <ProgressCircle size="medium" style={{ ...progressCircleStyle }} className={progressCircleClass} containerClass={progressCircleContainerClass} /> ) : ( "" )} </td> ); })} </tr> ) : message ? ( <tr style={{ height: 40, fontFamily: "Roboto, sans-serif", fontSize: "16px", ...tableRowStyles, }} > {columns.map((column, index) => { return ( <td key={`message-${index}-${key ? key : ""}`} style={{ justifyContent: "center", alignItems: "center", width: columnWidth, paddingInline: "6px", ...column?.style, }} > {index === Math.floor(columns.length / 2) ? ( <div style={{ fontSize: "14px", ...noDataStyle }}> {message ? message : ""} </div> ) : ( "" )} </td> ); })} </tr> ) : ( data?.map((value, rowIndex) => { return ( <tr key={`tableRow-${rowIndex}-${key ? key : ""}`} id={value?.id} style={{ borderBottom: rowIndex !== data?.length - 1 ? "1px solid #d7d7d7" : "", height: 40, fontFamily: "Roboto, sans-serif", fontSize: "16px", ...tableRowStyles, }} > {columns?.map((column, index) => { return ( <td key={`tableColumn-${index}-${key ? key : ""}`} id={ value?.hasOwnProperty(column?.fieldName) ? value[column?.fieldName] : value?.hasOwnProperty(column?.label) ? value[column?.label] : `action-${value?.id}` } style={{ width: columnWidth, paddingInline: "12.5px", ...column?.style, }} > {column?.customBodyRenderer ? ( column.customBodyRenderer(value, rowIndex) ) : column?.type === "date" ? ( formatTimestampToDateString( value?.[ column?.fieldName ? column?.fieldName : column?.label ] ) ) : column?.type === "chip" ? ( renderChip(value, column) ) : column?.element ? ( <div onClick={(e) => actionHandler && actionHandler(e.currentTarget, value) } className="sortIcon" > {column?.element} </div> ) : column?.type === "link" ? ( <span onClick={(e) => linkHandler && linkHandler(e, value) } className="sortIcon" style={{ color: "rgb(2, 167, 240)", }} > { value?.[ column?.fieldName ? column?.fieldName : column?.label ] } </span> ) : ( value?.[ column?.fieldName ? column?.fieldName : column?.label ] )} </td> ); })} </tr> ); }) )} </tbody> </table> </div> ); }; const styles = { tableHeader: { color: "#7f7f7f", fontSize: "12px", fontWeight: "700", fontFamily: "Roboto, sans-serif", paddingLeft: "12.5px", }, };