{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "table", "type": "registry:component", "title": "Table", "description": "Componente Concorde Table — un solo archivo, Table.tsx.", "dependencies": [ "react" ], "registryDependencies": [], "files": [ { "path": "components/Table.tsx", "type": "registry:file", "target": "components/Table.tsx", "content": "\"use client\";\n\n/**\n * Table — Generado por Concorde\n * Fuente: Figma VOYAGER · \"Container\" (1435:12215)\n *\n * Tabla de datos: header con gradiente morado (#8460E5 → #3B1782), texto de\n * encabezado blanco en mayúsculas, celdas con divisores #E1E3E2, contenedor\n * con radius 8 y overflow oculto. Data-driven: `columns` + `rows` (cada celda\n * es un ReactNode → texto, CheckIcon, guion, botones de icono, etc.).\n * Self-contained (CSS-in-JS, zero deps), con scroll horizontal.\n */\n\nimport type { JSX, ReactNode } from \"react\";\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport type TableAlign = \"left\" | \"center\" | \"right\";\n\nexport interface TableColumn {\n /** Texto/Nodo del encabezado */\n header: ReactNode;\n /** Alineación de la columna (default \"left\") */\n align?: TableAlign;\n /** Ancho fijo opcional (px o cualquier unidad CSS) */\n width?: number | string;\n}\n\nexport interface TableProps {\n /** Definición de columnas (encabezados) */\n columns: TableColumn[];\n /** Filas: cada una es un arreglo de celdas alineado a `columns` */\n rows: ReactNode[][];\n /** Texto accesible de la tabla (caption, oculto visualmente) */\n caption?: string;\n className?: string;\n}\n\n// ─── Self-contained CSS ───────────────────────────────────────────────────────\n\nconst STYLE_ID = \"concorde-table-styles\";\n\nconst TABLE_STYLES = `\n.ptable__scroll {\n width: 100%;\n overflow-x: auto;\n border-radius: 8px;\n background: #ffffff;\n box-shadow: rgba(32,0,104,0.06) 0px 1px 2px, rgba(32,0,104,0.10) 0px 12px 32px;\n}\n.ptable {\n border-collapse: collapse;\n width: 100%;\n font-family: var(--vmc-font-display, \"Plus Jakarta Sans\", -apple-system, sans-serif);\n background: #ffffff;\n}\n/* Header: una sola gradiente continua de izquierda a derecha sobre toda la fila */\n.ptable thead tr {\n background-image: linear-gradient(90deg, #8460E5 0%, #3B1782 100%);\n}\n.ptable__th {\n position: relative;\n padding: 12px 24px;\n text-align: left;\n vertical-align: middle;\n white-space: nowrap;\n font-size: 12px;\n font-weight: 600;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: #ffffff;\n background: transparent;\n border-bottom: 1px solid rgba(0,0,0,0.5);\n}\n.ptable__td {\n padding: 18px 24px;\n vertical-align: middle;\n font-size: 14px;\n font-weight: 500;\n line-height: 20px;\n color: #070C0C;\n border-bottom: 1px solid #E1E3E2;\n}\n.ptable tbody tr:last-child .ptable__td { border-bottom: none; }\n.ptable__align-center { text-align: center; }\n.ptable__align-right { text-align: right; }\n`;\n\nlet _stylesInjected = false;\n\n// ─── Component ────────────────────────────────────────────────────────────────\n\nfunction alignClass(align: TableAlign | undefined): string {\n if (align === \"center\") return \" ptable__align-center\";\n if (align === \"right\") return \" ptable__align-right\";\n return \"\";\n}\n\nexport default function Table({ columns, rows, caption, className = \"\" }: TableProps): JSX.Element {\n if (typeof document !== \"undefined\" && !_stylesInjected) {\n if (!document.getElementById(STYLE_ID)) {\n const el = document.createElement(\"style\");\n el.id = STYLE_ID;\n el.textContent = TABLE_STYLES;\n document.head.appendChild(el);\n }\n _stylesInjected = true;\n }\n\n return (\n <>\n \n
| \n {col.header}\n | \n );\n })}\n
|---|
| \n {row[c]}\n | \n );\n })}\n