({ id, code }: ViewerProps)
| 73 | } |
| 74 | |
| 75 | export default function CodeViewer({ id, code }: ViewerProps) { |
| 76 | const item = useAtomValue(historyAtomFamily({ id })) |
| 77 | const uiTheme = useAtomValue(uiThemeAtom) |
| 78 | const theme = themes.find(t => t.name === uiTheme) |
| 79 | const [framework, setFramework] = useAtom(selectedFrameworkAtom) |
| 80 | const [convertFramework, setConvertFramework] = useAtom(convertFrameworkAtom) |
| 81 | |
| 82 | // Local state |
| 83 | const [currentCode, setCurrentCode] = useState<string>(code) |
| 84 | |
| 85 | // TODO: likely throttle / debounce |
| 86 | useEffect(() => { |
| 87 | if (framework === 'jsx') { |
| 88 | setCurrentCode(htmlToJSX(code)) |
| 89 | } else if (framework === 'html') { |
| 90 | setCurrentCode(code) |
| 91 | } else { |
| 92 | setCurrentCode( |
| 93 | stripCodeblocks(item.components?.[framework] ?? 'Loading...') |
| 94 | ) |
| 95 | } |
| 96 | }, [framework, code, item.components]) |
| 97 | |
| 98 | useEffect(() => { |
| 99 | if (convertFramework) { |
| 100 | setFramework(convertFramework) |
| 101 | } |
| 102 | }, [convertFramework, setFramework]) |
| 103 | |
| 104 | // TODO: do I need an effect for components changing? |
| 105 | const frameworks: Framework[] = ['html'] |
| 106 | if (item.components) { |
| 107 | frameworks.push(...(Object.keys(item.components) as Framework[])) |
| 108 | } else { |
| 109 | frameworks.push('jsx') |
| 110 | } |
| 111 | |
| 112 | return ( |
| 113 | <div className='code-syntax-wrapper'> |
| 114 | <div className='code-syntax relative rounded-lg border'> |
| 115 | <div className='grid w-full grid-cols-4 rounded-t-md border-b'> |
| 116 | <ul className='z-10 col-span-3 flex max-h-9 w-full overflow-x-auto overflow-y-hidden rounded-tl-lg bg-background text-center text-sm font-medium text-gray-500 dark:text-gray-400'> |
| 117 | {frameworks.map((f, i) => ( |
| 118 | <li key={f}> |
| 119 | <button |
| 120 | type='button' |
| 121 | onClick={() => setFramework(f)} |
| 122 | className={cn( |
| 123 | 'inline-block w-full whitespace-nowrap border-r p-2 px-3 text-secondary-foreground', |
| 124 | f === framework |
| 125 | ? 'bg-background' |
| 126 | : 'bg-secondary hover:bg-background', |
| 127 | i === 0 && 'rounded-tl-lg' |
| 128 | )} |
| 129 | > |
| 130 | {f.toUpperCase()} |
| 131 | </button> |
| 132 | </li> |
nothing calls this directly
no test coverage detected