UNPKG

polen

Version:

A framework for delightful GraphQL developer portals

71 lines 4.14 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { CRITICALITY_CONFIG, isCriticalityBreaking, isCriticalityDangerous, isCriticalitySafe, } from '#lib/graphql-change/criticality'; import { Box, Flex, Text } from '@radix-ui/themes'; import { useEffect, useState } from 'react'; import { renderDate } from './Changelog.js'; const calculateCounts = (version) => { return { breaking: version.changes.filter(isCriticalityBreaking).length, dangerous: version.changes.filter(isCriticalityDangerous).length, safe: version.changes.filter(isCriticalitySafe).length, }; }; const SidebarEntry = ({ version, counts, isActive }) => { const dateId = version.date.toISOString(); return (_jsx(Box, { mb: '2', children: _jsxs("a", { href: `#${dateId}`, style: { textDecoration: 'none', display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '0.5rem 0.75rem', borderRadius: '4px', backgroundColor: isActive ? 'var(--gray-a3)' : 'transparent', color: 'inherit', transition: 'background-color 0.2s', }, onClick: (e) => { e.preventDefault(); document.getElementById(dateId)?.scrollIntoView({ behavior: 'smooth' }); }, children: [_jsx(Text, { size: '2', weight: isActive ? 'medium' : 'regular', children: renderDate(version.date) }), _jsxs(Flex, { gap: '2', align: 'center', children: [counts.breaking > 0 && (_jsx(Text, { size: '1', weight: 'medium', style: { color: CRITICALITY_CONFIG.BREAKING.color }, children: counts.breaking })), counts.dangerous > 0 && (_jsx(Text, { size: '1', weight: 'medium', style: { color: CRITICALITY_CONFIG.DANGEROUS.color }, children: counts.dangerous })), counts.safe > 0 && (_jsx(Text, { size: '1', weight: 'medium', style: { color: CRITICALITY_CONFIG.NON_BREAKING.color }, children: counts.safe }))] })] }) })); }; export const ChangelogLayout = ({ children, versions }) => { const [activeVersion, setActiveVersion] = useState(null); // Calculate counts for all versions (SSR-safe) const versionsWithCounts = versions.map(version => ({ version, counts: calculateCounts(version), })); // Set up scroll spy after hydration useEffect(() => { const handleScroll = () => { const scrollPosition = window.scrollY + 100; // Offset for header // Find the current version based on scroll position let currentVersion = null; for (const { version } of versionsWithCounts) { const element = document.getElementById(version.date.toISOString()); if (element) { const { top } = element.getBoundingClientRect(); if (top <= 100) { currentVersion = version.date.toISOString(); } } } setActiveVersion(currentVersion); }; // Initial check handleScroll(); // Add scroll listener window.addEventListener('scroll', handleScroll, { passive: true }); return () => { window.removeEventListener('scroll', handleScroll); }; }, [versionsWithCounts]); return (_jsxs(Flex, { gap: '6', style: { position: 'relative' }, children: [_jsxs(Box, { style: { position: 'sticky', top: '2rem', height: 'fit-content', minWidth: '250px', maxHeight: 'calc(100vh - 4rem)', overflowY: 'auto', }, children: [_jsx(Text, { size: '2', weight: 'medium', mb: '3', style: { display: 'block' }, children: "Releases" }), versionsWithCounts.map(({ version, counts }) => (_jsx(SidebarEntry, { version: version, counts: counts, isActive: activeVersion === version.date.toISOString() }, version.date.toISOString())))] }), _jsx(Box, { style: { flex: 1, minWidth: 0 }, children: children })] })); }; //# sourceMappingURL=ChangelogLayout.js.map