import { useEffect, useRef, useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { Lang, Theme } from 'shiki'; import { useTheme } from '../../hooks/useTheme'; type ThemePreviewProps = { id: string; theme: Theme; lang: Lang; code: string; fontSize: string; lineHeight: string; fontFamily: string; onClick: () => void; }; export const ThemePreview = ({ id, theme, lang, onClick, code, fontSize, lineHeight, fontFamily, }: ThemePreviewProps) => { const [inView, setInView] = useState(false); const { highlighter, error, loading } = useTheme({ theme, // If no code is written yet, show a classic Carmack snippet lang: code ? lang : 'c', ready: inView, }); const [codeRendered, setCode] = useState(''); const [backgroundColor, setBg] = useState('#ffffff'); const observer = useRef( new IntersectionObserver(([entry]) => { if (entry.isIntersecting) { setInView(true); observer.current.disconnect(); } }), ); const codeSnippet = ` float Q_rsqrt( float number ) { long i; float x2, y; const float threehalfs = 1.5F; x2 = number * 0.5F; y = number; i = * ( long * ) &y; // evil floating point bit level hacking i = 0x5f3759df - ( i >> 1 ); // what the frack? y = * ( float * ) &i; y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration // y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed return y; }`.trim(); useEffect(() => { if (!highlighter) return; const hl = code ? highlighter.codeToHtml(code, { lang }) : highlighter.codeToHtml(codeSnippet, { lang: 'c' }); setCode(hl); setBg(highlighter.getBackgroundColor()); }, [highlighter, lang, code, codeSnippet]); return ( ); };