import React from 'react'; import { H1, H2, H3, H4, H5 } from '@cloudflare/elements'; import { createStyledComponent, ThemeProp } from '@cloudflare/style-container'; type SectionProps = { children: React.ReactNode; level?: number; offset?: number; }; type HeadingProps = React.ComponentProps & { level?: number; offset?: number; role?: string; }; const HeadingInfo = React.createContext({ level: 0, offset: 0 }); const headerThemes = [ ({ theme }: { theme: ThemeProp['theme'] }) => ({ fontSize: theme.fontSizes[6], lineHeight: 1.25, color: theme.colors.gray[1], fontWeight: 600 }), ({ theme }: { theme: ThemeProp['theme'] }) => ({ fontSize: theme.fontSizes[5], lineHeight: 1.25, color: theme.colors.gray[3], fontWeight: 400 }), ({ theme }: { theme: ThemeProp['theme'] }) => ({ fontSize: theme.fontSizes[4], fontWeight: 600 }), ({ theme }: { theme: ThemeProp['theme'] }) => ({ fontSize: theme.fontSizes[3], lineHeight: 1.25, fontWeight: 600 }) ]; const headings = [H1, H2, H3, H4, H5]; const maxHeadingLevel = headings.length - 1; const maxOffset = 2; const standardHeadings = headings.map((h, index) => { const themeIndex = Math.min(index, headerThemes.length); return createStyledComponent(headerThemes[themeIndex], h); }); // Renders H1 with H2 style, H2 with H3 style etc. const offsetOneHeadings = headings.map((h, index) => { const themeIndex = Math.min(index + 1, headerThemes.length); return createStyledComponent(headerThemes[themeIndex], h); }); // Renders H1 with H3 style, H2 with H4 style etc. const offsetTwoHeadings = headings.map((h, index) => { const themeIndex = Math.min(index + 2, headerThemes.length); return createStyledComponent(headerThemes[themeIndex], h); }); export function Section(props: SectionProps) { return ( {info => ( {props.children} )} ); } export function Heading({ level, offset = 0, role, ...props }: HeadingProps) { return ( {info => { const headingOffset = Math.min(maxOffset, info.offset + offset); const headings = headingOffset === 1 ? offsetOneHeadings : headingOffset === 2 ? offsetTwoHeadings : standardHeadings; const headingLevel = Math.min( level !== undefined ? level - 1 : info.level, maxHeadingLevel ); const Heading = headings[Math.max(0, headingLevel)]; // @ts-ignore return ; }} ); }