Repository: wandb/openui
File: frontend/src/components/HtmlAnnotator.tsx (TypeScript)

Code before:

	// global state
	const setAnnotatedHTML = useSetAtom(annotatedHTMLAtom)
	const setScreenshot = useSetAtom(screenshotAtom)
	const [comments, setComments] = useAtom(commentsAtom)
	const [darkMode, setDarkMode] = useAtom(darkModeAtom)

	// local state
	const [preview, setPreview] = useState<boolean>(false)
	const [inspectorEnabled, setInspectorEnabled] = useState<boolean>(false)
	const [bufferedHTML, setBufferedHTML] = useState<string | undefined>()
	const [media, setMedia] = useState<'desktop' | 'mobile' | 'tablet'>('desktop')

	useLayoutEffect(() => {
		setDarkMode(window.matchMedia('(prefers-color-scheme: dark)').matches)
	}, [setDarkMode])

	// iframe content
	useEffect(() => {
		if (!bufferedHTML) {
			setPreview(false)
		}
		if (iframeRef.current) {
			iframeRef.current.contentWindow?.postMessage(
				{
					html: bufferedHTML,
					js: rendering ? [] : js,
					darkMode,
					action: 'hydrate'
				},
				'*'
			)
		}
	}, [bufferedHTML, darkMode, js, rendering, iframeRef])

	useEffect(() => {
		if (iframeRef.current) {
			let lines = html.split('\n')
			const lineBreak = 80
			const minBuffer = 3
			const lastLine = -1
			// Let comments flow through, breaking at 80 chars
			if (lines.at(lastLine)?.startsWith('<!--')) {
				const comment = lines.pop()
				lines = [...lines, ...breakString(comment ?? '', lineBreak)]
			} else if (!lines.at(lastLine)?.endsWith('>')) {
				lines.pop()
			}
			// TODO: we could play around with this more
			if (lines.length > minBuffer || !rendering) {
				setBufferedHTML(lines.join('\n'))

Review comment (suggestion):
Thanks for the PR @xiaopeng-ye, I didn't want to do this initially because the darkmode toggle was meant to only effect the rendered HTML not the outer shell of the application.  The more I think about it though, this is probably what I would want.  As it stands today I'm setting darkMode for the outershell based on the OS setting only.  I'll merge, thanks again!

Code after:
	const item = useAtomValue(historyAtomFamily({ id }))

	// global state
	const setAnnotatedHTML = useSetAtom(annotatedHTMLAtom)
	const setScreenshot = useSetAtom(screenshotAtom)
	const [comments, setComments] = useAtom(commentsAtom)
	const [darkMode, setDarkMode] = useAtom(darkModeAtom)

	// local state
	const [preview, setPreview] = useState<boolean>(false)
	const [inspectorEnabled, setInspectorEnabled] = useState<boolean>(false)
	const [bufferedHTML, setBufferedHTML] = useState<string | undefined>()
	const [media, setMedia] = useState<'desktop' | 'mobile' | 'tablet'>('desktop')

	useLayoutEffect(() => {
		setDarkMode(window.matchMedia('(prefers-color-scheme: dark)').matches)
	}, [setDarkMode])

	useEffect(() => {
		if (darkMode) {
			document.documentElement.classList.add('dark')
		} else {
			document.documentElement.classList.remove('dark')
		}
	}, [darkMode])

	// iframe content
	useEffect(() => {
		if (!bufferedHTML) {
			setPreview(false)
		}
		if (iframeRef.current) {
			iframeRef.current.contentWindow?.postMessage(
				{
					html: bufferedHTML,
					js: rendering ? [] : js,
					darkMode,
					action: 'hydrate'
				},
				'*'
			)
		}
	}, [bufferedHTML, darkMode, js, rendering, iframeRef])

	useEffect(() => {
		if (iframeRef.current) {
			let lines = html.split('\n')
			const lineBreak = 80
			const minBuffer = 3
			const lastLine = -1
			// Let comments flow through, breaking at 80 chars