({ json, highlightPath }: JsonPreviewProps)
| 24 | }; |
| 25 | |
| 26 | export function JsonPreview({ json, highlightPath }: JsonPreviewProps) { |
| 27 | const editor = useRef(null); |
| 28 | const [preferences] = usePreferences(); |
| 29 | |
| 30 | const jsonMapped = useMemo(() => { |
| 31 | return jsonMap.stringify(json, null, preferences?.indent || 2); |
| 32 | }, [json, preferences]); |
| 33 | |
| 34 | const lines: LineRange | undefined = useMemo(() => { |
| 35 | if (!highlightPath) { |
| 36 | return; |
| 37 | } |
| 38 | |
| 39 | let path = new JSONHeroPath(highlightPath); |
| 40 | let pointer = path.jsonPointer(); |
| 41 | |
| 42 | let selectionInfo = jsonMapped.pointers[pointer]; |
| 43 | |
| 44 | return { |
| 45 | from: selectionInfo.value.line + 1, |
| 46 | to: selectionInfo.valueEnd.line + 1, |
| 47 | }; |
| 48 | }, [jsonMapped, highlightPath]); |
| 49 | |
| 50 | const extensions = getPreviewSetup(); |
| 51 | |
| 52 | const highlighting = new Compartment(); |
| 53 | |
| 54 | if (lines) { |
| 55 | extensions.push(highlighting.of(highlightLineRange(lines))); |
| 56 | } |
| 57 | |
| 58 | const [theme] = useTheme(); |
| 59 | |
| 60 | const { setContainer, view, state } = useCodeMirror({ |
| 61 | container: editor.current, |
| 62 | extensions, |
| 63 | value: jsonMapped.json, |
| 64 | editable: false, |
| 65 | contentEditable: false, |
| 66 | autoFocus: false, |
| 67 | basicSetup: false, |
| 68 | theme: theme === "light" ? lightTheme() : darkTheme(), |
| 69 | }); |
| 70 | |
| 71 | useEffect(() => { |
| 72 | if (editor.current) { |
| 73 | setContainer(editor.current); |
| 74 | } |
| 75 | }, [editor.current]); |
| 76 | |
| 77 | useEffect(() => { |
| 78 | if (!view) { |
| 79 | return; |
| 80 | } |
| 81 | |
| 82 | let transactionSpec: TransactionSpec = { |
| 83 | changes: { from: 0, to: view.state.doc.length, insert: jsonMapped.json }, |
nothing calls this directly
no test coverage detected