import React, { createContext, useContext, useMemo } from "react"; import { useTbodyContext } from "./tbody"; interface TrContextValue { columnCount: number; columnWidths: number[]; rowHeight: number; // Context exists to ensure Th is wrapped in Thead // The colIndex is injected via props by React.cloneElement } const TrContext = createContext(null); export const useTrContext = (): TrContextValue => { const context = useContext(TrContext); if (!context) { throw new Error("Tr component must be used inside Tbody component"); } return context; }; interface TrProps extends React.HTMLAttributes { rowIndex?: number; // This prop is automatically injected by Tbody via React.cloneElement } const Tr = ({ children, style, rowIndex, ...props }: TrProps) => { // Ensure Tr is used within Tbody context - throws error if not wrapped const { contentWidth, rowHeight, columnCount, columnWidths } = useTbodyContext(); // rowIndex is injected by Tbody component via React.cloneElement as absolute index // If it's missing, that's an error condition if (rowIndex === undefined) { throw new Error( "Tr component must receive rowIndex prop. Make sure it's used inside Tbody component." ); } const contextValue: TrContextValue = useMemo( () => ({ columnCount, columnWidths, rowHeight, }), [columnCount, columnWidths, rowHeight] ); let currentColIndex = 0; return (
{React.Children.map(children, (child) => { if (React.isValidElement(child)) { const colSpan = (child.props as any).colSpan || 1; const index = currentColIndex; currentColIndex += colSpan; return React.cloneElement(child, { colIndex: index } as any); } return child; })}
); }; export default Tr;