diff --git a/src/components/Changelog.tsx b/src/components/Changelog.tsx index c66f9bf..73e1e36 100644 --- a/src/components/Changelog.tsx +++ b/src/components/Changelog.tsx @@ -10,6 +10,7 @@ const tagStyles: Record = { improvement: 'border-blue-500/30 bg-blue-500/[0.08] text-blue-400', fix: 'border-amber-500/30 bg-amber-500/[0.08] text-amber-400', beta: 'border-purple-500/30 bg-purple-500/[0.08] text-purple-400', + pivot: 'border-rose-500/40 bg-rose-500/[0.10] text-rose-300', }; const sectionDotColor: Record = { @@ -18,7 +19,18 @@ const sectionDotColor: Record = { fix: 'bg-amber-400', }; -function EntryCard({ entry, index }: { entry: ChangelogEntry; index: number }) { +/** + * One changelog release, laid out as a vertical timeline row — Mintlify-style: + * a sticky version label on the left rail, a node on the connecting line, and + * the release content to the right. + */ +function TimelineEntry({ + entry, + index, +}: { + entry: ChangelogEntry; + index: number; +}) { const [expandedSections, setExpandedSections] = useState< Record >({}); @@ -27,112 +39,127 @@ function EntryCard({ entry, index }: { entry: ChangelogEntry; index: number }) { setExpandedSections(prev => ({ ...prev, [i]: !prev[i] })); }; + const isPivot = entry.tag === 'pivot'; + return ( - {/* Card header */} -
-
- - {entry.version} - - · - - {entry.date} - - {entry.tag && ( - - {entry.tag} - - )} + {/* Left rail — version, date, tag (sticky on desktop) */} +
+
+ {entry.version}
-

- {entry.title} -

+
+ {entry.date} +
+ {entry.tag && ( + + {entry.tag} + + )}
- {/* Sections */} -
- {entry.sections.map((section, si) => { - const isCollapsible = section.collapsible; - const isExpanded = expandedSections[si] ?? false; + {/* Connecting line + node + release content */} +
+ + +

+ {entry.title} +

- return ( -
- {isCollapsible ? ( - /* Collapsible section */ -
- +
+ {entry.sections.map((section, si) => { + const isCollapsible = section.collapsible; + const isExpanded = expandedSections[si] ?? false; - {isExpanded && ( - + {isCollapsible ? ( + /* Collapsible section */ +
+ + + {isExpanded && ( + + {section.items.map((item, ii) => ( +

+ + {item.label}: + {' '} + {item.description} +

+ ))} +
+ )} +
+ ) : ( + /* Normal section */ +
+
+ +

+ {section.label} +

+
+
    {section.items.map((item, ii) => ( -

    - - {item.label}: - {' '} - {item.description} -

    +
  • + +

    + + {item.label}: + {' '} + {item.description} +

    +
  • ))} - - )} -
- ) : ( - /* Normal section */ -
-
- -

- {section.label} -

+
-
    - {section.items.map((item, ii) => ( -
  • - -

    - - {item.label}: - {' '} - {item.description} -

    -
  • - ))} -
-
- )} -
- ); - })} + )} +
+ ); + })} +
); @@ -222,7 +249,7 @@ const Changelog: React.FC = () => { initial={{ opacity: 0, y: 12 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.4, delay: 0.1 }} - className="flex gap-1 mb-10 p-1 rounded-xl bg-white/[0.04] border border-white/[0.08] w-fit" + className="flex gap-1 mb-12 p-1 rounded-xl bg-white/[0.04] border border-white/[0.08] w-fit" > {(['web', 'cli'] as Tab[]).map(t => (