UNPKG

@blocktion/json-to-table

Version:

A powerful, modular React component for converting JSON data to navigable tables with advanced features like automatic column detection, theming, and sub-table navigation. Part of the Blocktion SaaS project ecosystem.

88 lines (87 loc) 3.99 kB
import { jsx as _jsx } from "react/jsx-runtime"; import { NavigableCell } from "./NavigableCell"; import { useTheme } from "../../styles/theme-provider"; import { TableCell } from "../../styles/styled-components"; export const CellRenderer = ({ column, row, value, onNavigateToSubTable, onCellClick, onCellDoubleClick, enableNavigation, customRenderers = {}, rowIndex, }) => { const { theme } = useTheme(); const handleCellClick = () => { onCellClick?.(value, column, row); }; const handleCellDoubleClick = () => { onCellDoubleClick?.(value, column, row); }; const handleNavigate = () => { const valueIsArray = Array.isArray(value); const valueIsObject = !!value && typeof value === "object" && !Array.isArray(value); let isNavigable = valueIsArray || valueIsObject; if (!isNavigable && column.columnType.isNavigable) { isNavigable = valueIsArray || valueIsObject; } if (!enableNavigation || !isNavigable) return; let title; if (valueIsArray || column.columnType.isArray) { title = `${column.displayName} (Array)`; } else if (valueIsObject || column.columnType.isObject) { title = `${column.displayName} (Object)`; } else { title = `${column.displayName} (Value)`; } onNavigateToSubTable(column.cleanKey, value, title, rowIndex); }; const formatValue = (val) => { if (val === null || val === undefined) return ""; if (typeof val === "string") { return val.length > 30 ? val.substring(0, 27) + "..." : val; } if (typeof val === "object" && val !== null) { const jsonStr = JSON.stringify(val); return jsonStr.length > 30 ? jsonStr.substring(0, 27) + "..." : jsonStr; } return String(val); }; // Custom renderer from column definition if (column.renderer) { return (_jsx(TableCell, { onClick: handleCellClick, onDoubleClick: handleCellDoubleClick, children: column.renderer(value, row) })); } // Custom renderer from props if (customRenderers[column.cleanKey]) { return (_jsx(TableCell, { onClick: handleCellClick, onDoubleClick: handleCellDoubleClick, children: customRenderers[column.cleanKey](value, row) })); } // Navigable cell const valueIsArray = Array.isArray(value); const valueIsObject = !!value && typeof value === "object" && !Array.isArray(value); let isNavigableNow = enableNavigation && (valueIsArray || valueIsObject); if (!isNavigableNow && column.columnType.isNavigable) { isNavigableNow = enableNavigation && (valueIsArray || valueIsObject); } if (isNavigableNow && value) { let displayText; let type; if (valueIsArray || column.columnType.isArray) { displayText = `${value.length} items`; type = "array"; } else if (valueIsObject || column.columnType.isObject) { // Show object key count for better context const obj = value; const keyCount = Object.keys(obj).length; displayText = keyCount === 1 ? "1 property" : `${keyCount} properties`; type = "object"; } else { displayText = formatValue(value); type = "object"; } return (_jsx(TableCell, { onClick: handleCellClick, onDoubleClick: handleCellDoubleClick, children: _jsx(NavigableCell, { value: value, displayText: displayText, onNavigate: handleNavigate, type: type }) })); } // Regular cell return (_jsx(TableCell, { onClick: handleCellClick, onDoubleClick: handleCellDoubleClick, children: _jsx("span", { style: { color: value === null || value === undefined ? theme.colors.text.muted : theme.colors.text.primary, }, children: formatValue(value) }) })); };