Files
alirez.brandCursor a47ec493c5 feat: add version history drawer with release notes
Introduce a footer-triggered Version History drawer with categorized release notes, hardcoded release data, and semver tracking at v0.3.0. Also ships blog blockquote/table styling, site-wide typography, home page image updates, header refinements, and related bug fixes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-02 02:46:20 +03:30

66 lines
2.0 KiB
TypeScript

import type { TableBlockPayload } from "@/lib/blog-blocks";
import { tableVariantClass } from "@/components/blog-table-styles";
import { cn } from "@/lib/utils";
interface BlogTableProps {
payload: TableBlockPayload;
}
/** Glass shell — matches HeroHeader bar styling. */
const tableGlassClass =
"rounded-blog border border-border/10 bg-background/30 backdrop-blur-md shadow-lg overflow-hidden transition-[box-shadow,background-color] duration-300";
export function BlogTable({ payload }: BlogTableProps) {
const { headers, rows, caption, variant = "one" } = payload;
if (!headers.length && !rows.length) return null;
return (
<figure
className={cn(
"blog-table not-prose my-8 text-foreground",
tableGlassClass,
tableVariantClass[variant]
)}
>
<div className="blog-table__scroll">
<table className="blog-table__grid">
{headers.length > 0 ? (
<thead>
<tr>
{headers.map((header, index) => (
<th
key={index}
scope="col"
dangerouslySetInnerHTML={{ __html: header }}
/>
))}
</tr>
</thead>
) : null}
{rows.length > 0 ? (
<tbody>
{rows.map((row, rowIndex) => (
<tr key={rowIndex}>
{row.map((cell, cellIndex) => {
const Tag = cellIndex === 0 && headers.length === 0 ? "th" : "td";
return (
<Tag
key={cellIndex}
{...(Tag === "th" ? { scope: "row" as const } : {})}
dangerouslySetInnerHTML={{ __html: cell }}
/>
);
})}
</tr>
))}
</tbody>
) : null}
</table>
</div>
{caption ? (
<figcaption className="blog-table__caption">{caption}</figcaption>
) : null}
</figure>
);
}