"use client" import React, { useState } from 'react'; import { Badge } from './badge'; import { ChevronDown } from 'lucide-react'; import { FadePreview } from './fade-preview'; import { RichMarkdownRenderer } from './markdown'; import type { ChangelogEntry } from '../../types/product-release'; interface ReleaseChangelogSectionProps { title: string; entries: ChangelogEntry[]; isBreaking?: boolean; hideTitle?: boolean; /** When true, section starts collapsed and can be toggled open/closed * via a button on the title row. Mutually exclusive with `previewFirst`. */ collapsible?: boolean; /** Initial collapsed state (only used when collapsible=true). Defaults to true (collapsed). */ defaultCollapsed?: boolean; /** When true, render the first entry in full and fade-mask the rest * with a "Show N more / Show less" toggle below the list. Hides the * fade + toggle when there's only one entry. Mutually exclusive with * `collapsible` — when both are passed, `collapsible` wins. * * This is the same progressive-disclosure pattern used on the * investor-update detail page's Key Highlights / Financial Notes * sections (formerly a duplicated `FadedHighlightSection` component * in the hub — unified here). */ previewFirst?: boolean; /** Optional lucide icon rendered inline before the title text. Matches the * catalog card's changelog-strip icons (Sparkles for Features, Wrench for * Fixes, TrendingUp for Improvements, AlertTriangle for Breaking) — same * visual taxonomy across catalog and detail. Inherits the title's color * (secondary for normal sections, red for breaking). */ icon?: React.ReactNode; /** Markdown renderer for each entry's description. Optional — defaults to * the lib's `RichMarkdownRenderer` so changelog rich-link previews * (YouTube, OG cards, etc.) work out of the box. Hosts that already * wrap with a Supabase-aware preset can keep passing their own. */ MarkdownRenderer?: React.ComponentType<{ content: string }>; } // Collapsed height for the preview-first mode. ~120px shows the first // entry's title + the start of its description before the mask kicks in. const PREVIEW_COLLAPSED_HEIGHT = 120; export function ReleaseChangelogSection({ title, entries, isBreaking = false, hideTitle = false, collapsible = false, defaultCollapsed = true, previewFirst = false, icon, MarkdownRenderer = RichMarkdownRenderer, }: ReleaseChangelogSectionProps) { const [collapsed, setCollapsed] = useState(collapsible ? defaultCollapsed : false); if (!entries || entries.length === 0) return null; // collapsible wins when both flags are passed (documented in JSDoc). const inPreviewMode = previewFirst && !collapsible; const showEntries = !collapsible || !collapsed; return (
` typography which would override `text-h4` on `lg+` viewports and inflate the changelog body to 20px. The `[&_p]:!` overrides pin every descendant `
` back to the h4 responsive tokens so the breakpoints stay aligned with the rest of the page. */