Skip to content

Commit

Permalink
Made the editor load only when visible on the page
Browse files Browse the repository at this point in the history
  • Loading branch information
mattpocock committed Mar 11, 2024
1 parent 2c27785 commit 00232de
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 205 deletions.
26 changes: 9 additions & 17 deletions apps/total-typescript/src/components/code-editor/code-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,6 @@ export type CodeEditorProps = {
onEmittedJavaScript?: (code: string) => void
}

const getHeight = (code: string) => {
return code.split('\n').length * 24
}

let incrementable = 0

/**
Expand Down Expand Up @@ -86,14 +82,18 @@ export const EagerlyLoadedEditor = (props: CodeEditorProps) => {
return
}

const worker =
await monacoRef.current.languages.typescript.getTypeScriptWorker()
try {
const worker =
await monacoRef.current.languages.typescript.getTypeScriptWorker()

const client = await worker(uri)
const client = await worker(uri)

const emitOutput = await client.getEmitOutput(uri.toString())
const emitOutput = await client.getEmitOutput(uri.toString())

props.onEmittedJavaScript(emitOutput.outputFiles[0].text)
props.onEmittedJavaScript(emitOutput.outputFiles[0].text)
} catch (e) {
console.error('Getting emitted JavaScript failed', e)
}
}

return (
Expand Down Expand Up @@ -177,11 +177,3 @@ export const EagerlyLoadedEditor = (props: CodeEditorProps) => {
/>
)
}

export const EagerlyLoadedFullWidthEditor = (props: CodeEditorProps) => {
return (
<div className="my-10 rounded bg-[#1e2632] py-6">
<EagerlyLoadedEditor {...props} />
</div>
)
}
Original file line number Diff line number Diff line change
@@ -1,60 +1,42 @@
import React from 'react'
import type {Language} from './code-editor'
import React, {useLayoutEffect} from 'react'
import type {CodeEditorProps} from './code-editor'

export const LazyLoadedFullWidthEditor = React.lazy(() =>
const _LazyLoadedEditor = React.lazy(() =>
import('./code-editor').then((res) => {
return {
default: res.EagerlyLoadedFullWidthEditor,
default: res.EagerlyLoadedEditor,
}
}),
)

export const LazyLoadedTranspilePreview = React.lazy(() =>
import('./transpile-preview').then((res) => {
return {
default: res.EagerlyLoadedTranspilePreview,
}
}),
)
const LoadWhenVisible = (props: {children: React.ReactNode}) => {
const [isVisible, setIsVisible] = React.useState(false)

export const MDXEditor = (props: {children?: any}) => {
// Yes, we're diving into React's internals to grab the
// code from the <pre> element
const code = props.children?.props?.children?.props?.children
const ref = React.useRef<HTMLDivElement>(null)

if (!code) {
return null
}
React.useEffect(() => {
const observer = new IntersectionObserver(([entry]) => {
setIsVisible(entry.isIntersecting)
})

let language = props.children?.props?.children?.props?.className

if (language) {
language = language.replace('language-', '') as Language
}

return <LazyLoadedFullWidthEditor code={code} language={language} />
}
observer.observe(ref.current!)

export const MDXTranspilePreview = (props: {children?: any}) => {
// Yes, we're diving into React's internals to grab the
// code from the <pre> element
const code = props.children?.props?.children?.props?.children

if (!code) {
return null
}

let language = props.children?.props?.children?.props?.className

if (language) {
language = language.replace('language-', '') as Language
}
return () => {
observer.disconnect()
}
}, [])

return <LazyLoadedTranspilePreview code={code} language={language} />
return (
<div ref={ref} className="h-full">
{isVisible ? props.children : null}
</div>
)
}

export const EditorTest = () => {
export const LazyLoadedEditor = (props: CodeEditorProps) => {
return (
<LazyLoadedTranspilePreview language="ts" code={`const wow = () => {}`} />
<LoadWhenVisible>
<_LazyLoadedEditor {...props} />
</LoadWhenVisible>
)
}
86 changes: 86 additions & 0 deletions apps/total-typescript/src/components/code-editor/mdx-editor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import Image from 'next/image'
import {useState} from 'react'
import type {CodeEditorProps, Language} from './code-editor'
import {LazyLoadedEditor} from './lazy-loaded-editor'
import tsSvg from './ts-logo.svg'
import jsSvg from './js-logo.svg'

const getHeight = (code: string) => {
return (code.split('\n').length + 3) * 24
}

const extractCodeAndLanguage = (props: {children?: any}) => {
const code = props.children?.props?.children?.props?.children
let language = props.children?.props?.children?.props?.className

if (!code || !language) {
return null
}

language = language.replace('language-', '') as Language

return {code, language}
}

export const MDXEditor = (props: {children?: any}) => {
// Yes, we're diving into React's internals to grab the
// code from the <pre> element
const extracted = extractCodeAndLanguage(props)

if (!extracted) {
return null
}

const {code, language} = extracted

return (
<div
className="my-10 h-72 rounded bg-[#1e2632] py-6"
style={{
height: getHeight(code),
}}
>
<LazyLoadedEditor code={code} language={language} />
</div>
)
}

export const MDXTranspilePreview = (props: {children?: any}) => {
const extracted = extractCodeAndLanguage(props)
const [jsCode, setJsCode] = useState<string | undefined>(undefined)

if (!extracted) {
return null
}

const {code, language} = extracted

return (
<div className="not-prose my-10 grid grid-cols-1 gap-2 md:grid-cols-2">
<div className="relative h-60 rounded bg-[#1e2632] py-6 md:h-72">
<LazyLoadedEditor
code={code}
language={language}
onEmittedJavaScript={setJsCode}
fontSize={16}
/>
<div className="absolute bottom-6 left-6 flex items-center space-x-3 rounded bg-gray-700 pr-3">
<Image src={tsSvg} alt="TypeScript Logo" className="size-7 rounded" />
<span className="text-xs text-gray-100">TypeScript Code</span>
</div>
</div>
<div className="relative h-60 rounded bg-[#1e2632] py-6 md:h-72">
<LazyLoadedEditor
code={jsCode ?? ''}
language="js"
readonly
fontSize={12}
/>
<div className="absolute bottom-6 left-6 flex items-center space-x-3 rounded bg-gray-700 pr-3">
<Image src={jsSvg} alt="JavaScript Logo" className="size-7 rounded" />
<span className="text-xs text-gray-100">Emitted JavaScript</span>
</div>
</div>
</div>
)
}

This file was deleted.

2 changes: 1 addition & 1 deletion apps/total-typescript/src/components/mdx/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import toast from 'react-hot-toast'
import {useCopyToClipboard} from 'react-use'
import Balancer from 'react-wrap-balancer'
import {twMerge} from 'tailwind-merge'
import {MDXEditor, MDXTranspilePreview} from '../code-editor/lazy-loaded-editor'
import {MDXEditor, MDXTranspilePreview} from '../code-editor/mdx-editor'

export const MDXComponents = {
TypeError: (props) => <TypeError {...props} />,
Expand Down
105 changes: 0 additions & 105 deletions apps/total-typescript/src/pages/editor-test.tsx

This file was deleted.

0 comments on commit 00232de

Please sign in to comment.