From db61a621d5930878ea9dc5821177646e8c0744d0 Mon Sep 17 00:00:00 2001 From: Nathan Clevenger Date: Mon, 19 May 2025 12:17:30 -0500 Subject: [PATCH] chore(mdxe): add monaco dependencies --- packages/mdxe/package.json | 5 ++- packages/mdxe/src/components/NotebookCell.tsx | 41 +++++++++++++++++++ packages/mdxe/src/components/notebookCell.css | 3 ++ .../mdxe/src/components/useDebouncedValue.ts | 12 ++++++ packages/mdxe/src/index.ts | 12 ++---- 5 files changed, 64 insertions(+), 9 deletions(-) create mode 100644 packages/mdxe/src/components/NotebookCell.tsx create mode 100644 packages/mdxe/src/components/notebookCell.css create mode 100644 packages/mdxe/src/components/useDebouncedValue.ts diff --git a/packages/mdxe/package.json b/packages/mdxe/package.json index 84190f1..d6b8d08 100644 --- a/packages/mdxe/package.json +++ b/packages/mdxe/package.json @@ -14,7 +14,8 @@ "dist", "src/app", "src/config", - "src/payload" + "src/payload", + "src/components" ], "scripts": { "build": "tsc && chmod +x bin/mdxe.js", @@ -44,6 +45,8 @@ "react-dom": "^19.1.0", "sqlite3": "^5.1.6", "tailwindcss": "^3.4.1", + "@monaco-editor/react": "^4.5.1", + "monaco-editor": "^0.38.0", "undici": "^7.8.0", "vitest": "^3.1.3" }, diff --git a/packages/mdxe/src/components/NotebookCell.tsx b/packages/mdxe/src/components/NotebookCell.tsx new file mode 100644 index 0000000..a2facf5 --- /dev/null +++ b/packages/mdxe/src/components/NotebookCell.tsx @@ -0,0 +1,41 @@ +'use client' + +import { useState, useEffect } from 'react' +import Editor from '@monaco-editor/react' +import { useDebouncedValue } from './useDebouncedValue' + +export interface NotebookCellProps { + initialCode?: string + language?: string + className?: string + debounce?: number +} + +export const NotebookCell = ({ initialCode = '', language = 'javascript', className, debounce = 300 }: NotebookCellProps) => { + const [code, setCode] = useState(initialCode) + const [output, setOutput] = useState('') + + const debouncedCode = useDebouncedValue(code, debounce) + + useEffect(() => { + try { + const result = new Function(debouncedCode)() + if (result instanceof Promise) { + result.then((res) => setOutput(String(res))).catch((err) => setOutput(String(err))) + } else { + setOutput(String(result)) + } + } catch (err) { + setOutput(String(err)) + } + }, [debouncedCode]) + + return ( +
+ setCode(value || '')} options={{ minimap: { enabled: false } }} /> +
{output}
+
+ ) +} + +export default NotebookCell diff --git a/packages/mdxe/src/components/notebookCell.css b/packages/mdxe/src/components/notebookCell.css new file mode 100644 index 0000000..08cd32e --- /dev/null +++ b/packages/mdxe/src/components/notebookCell.css @@ -0,0 +1,3 @@ +.notebook-cell .monaco-editor { + border-bottom: 1px solid #e5e7eb; /* tailwind gray-200 */ +} diff --git a/packages/mdxe/src/components/useDebouncedValue.ts b/packages/mdxe/src/components/useDebouncedValue.ts new file mode 100644 index 0000000..918bc79 --- /dev/null +++ b/packages/mdxe/src/components/useDebouncedValue.ts @@ -0,0 +1,12 @@ +import { useState, useEffect } from 'react' + +export function useDebouncedValue(value: T, delay: number): T { + const [debounced, setDebounced] = useState(value) + + useEffect(() => { + const timer = setTimeout(() => setDebounced(value), delay) + return () => clearTimeout(timer) + }, [value, delay]) + + return debounced +} diff --git a/packages/mdxe/src/index.ts b/packages/mdxe/src/index.ts index 3838669..c944dd2 100644 --- a/packages/mdxe/src/index.ts +++ b/packages/mdxe/src/index.ts @@ -2,15 +2,11 @@ export const version = '0.1.0' export { useMDXComponents } from './app/mdx-components' +export { NotebookCell } from './components/NotebookCell' +export { useDebouncedValue } from './components/useDebouncedValue' + export { types } from './config/types.js' // export { createPayloadClient, getPayloadConfig } from './payload' -export { - isDirectory, - isMarkdownFile, - findIndexFile, - resolvePath, - getAllMarkdownFiles, - filePathToRoutePath -} from './utils/file-resolution.js' +export { isDirectory, isMarkdownFile, findIndexFile, resolvePath, getAllMarkdownFiles, filePathToRoutePath } from './utils/file-resolution.js'