Automerge backed Markdown editor for the Atmosphere
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940// src/layout/TabIcon.tsximport { useRef, useEffect } from 'react'import { getIcon, hasIcon } from '../plugin/ui/icon'
interface TabIconProps { iconName: string fallbackText: string}
/** * Renders a Lucide icon SVG from the icon registry via ref-based DOM mounting. * Falls back to the first letter of fallbackText when the icon name is unknown. * * Uses the same ref + useEffect pattern as RibbonIconElement (src/layout/Ribbon.tsx:9-17): * getIcon() is called inside useEffect with the iconName string as the dependency, * not the SVGElement return value (which is a new object on every call). * * The render-time branch decision uses hasIcon() — a pure registry lookup that * does NOT allocate an SVGElement — so no throwaway objects are created per render. */export function TabIcon({ iconName, fallbackText }: TabIconProps) { const ref = useRef<HTMLSpanElement>(null) const iconExists = hasIcon(iconName)
useEffect(() => { const el = ref.current if (!el) return const svg = getIcon(iconName) if (svg) { el.replaceChildren(svg) } }, [iconName])
if (!iconExists) { return <span className="tab-icon-fallback">{fallbackText.charAt(0)}</span> }
return <span ref={ref} className="tab-icon" />}