@moicad/gui
v0.1.6
Published
Reusable React components for moicad CAD platform
Maintainers
Readme
@moicad/gui
Reusable React components, hooks, and utilities for building CAD editor interfaces with moicad.
Installation
npm install @moicad/gui @moicad/sdk
# or
bun add @moicad/gui @moicad/sdkPeer Dependencies
This package requires the following peer dependencies:
react>= 18.0.0react-dom>= 18.0.0three>= 0.150.0
Usage
Basic Editor Setup
import { Editor, Viewport } from '@moicad/gui';
import { useState } from 'react';
function App() {
const [code, setCode] = useState('cube(10);');
const [geometry, setGeometry] = useState(null);
return (
<div style={{ display: 'flex', height: '100vh' }}>
<Editor
value={code}
onChange={setCode}
language="openscad"
/>
<Viewport geometry={geometry} />
</div>
);
}Full-Featured Editor (CADEditor Component)
The easiest way to get a complete CAD editor interface:
import { CADEditor } from '@moicad/gui/components';
function App() {
return (
<CADEditor
initialLanguage="javascript"
showFileManager={true}
showAnimationExport={true}
showTopMenu={true}
showPrinterSettings={true}
apiBaseUrl="http://localhost:42069" // Optional: API endpoint
/>
);
}CADEditor Props:
initialCode?: string- Starting code (default:cube(10);)initialLanguage?: 'openscad' | 'javascript'- Code languageapiBaseUrl?: string- API endpoint base URL (default: same origin)showFileManager?: boolean- Show file browser (default: true)showAnimationExport?: boolean- Show animation export features (default: true)showTopMenu?: boolean- Show top menu bar (default: true)showPrinterSettings?: boolean- Show printer presets (default: true)onCodeChange?: (code: string) => void- Code change callbackonGeometryUpdate?: (geometry: any) => void- Geometry update callbackonError?: (error: string) => void- Error callback
Custom Editor Layout
For more control, build your own layout with individual components:
import {
Editor,
Viewport,
TopMenu,
Sidebar,
FileManager,
AnimationControls,
ErrorDisplay,
StatsOverlay
} from '@moicad/gui/components';
import { useEditor, useGeometry, useAnimation } from '@moicad/gui/hooks';
import { evaluateCode } from '@moicad/gui/lib';
function CustomCADEditor() {
const editor = useEditor({ defaultCode: 'cube(10);' });
const geometry = useGeometry();
const animation = useAnimation();
const handleRender = async () => {
const result = await evaluateCode(editor.code, editor.language);
if (result.success) {
geometry.setGeometry(result.geometry);
}
};
return (
<div className="cad-editor">
<TopMenu onRender={handleRender} />
<div className="main-content">
<FileManager />
<Editor {...editor} onRender={handleRender} />
<Viewport {...geometry} />
<Sidebar geometry={geometry.current} />
</div>
{animation.isAnimation && (
<AnimationControls {...animation} />
)}
{geometry.error && <ErrorDisplay error={geometry.error} />}
<StatsOverlay stats={geometry.current?.stats} />
</div>
);
}Components
Editor Components
<Editor>- Monaco-based code editor with OpenSCAD/JavaScript syntax highlighting<FileManager>- File browser with save/load functionality<TopMenu>- Application menu bar (File, Edit, View, etc.)<ErrorDisplay>- Error message display with syntax highlighting
Viewport Components
<Viewport>- Three.js 3D viewport with orbit controls<ViewportWrapper>- Viewport with camera controls context<StatsOverlay>- Geometry statistics overlay (vertex count, faces, volume)
Control Components
<AnimationControls>- Timeline controls for animated models<Sidebar>- Export controls and settings panel<PrinterSettings>- 3D printer configuration presets<RenderProgressBar>- Render progress indicator
Utility Components
<ErrorBoundary>- React error boundary wrapper<ResizablePanel>- Draggable panel resizing
Hooks
useEditor(options)
Manages code editor state with localStorage persistence.
const editor = useEditor({
defaultCode: 'cube(10);',
language: 'openscad',
storageKey: 'my-editor'
});useGeometry()
Manages 3D geometry state and evaluation.
const { geometry, error, isLoading, evaluate } = useGeometry();useAnimation(options)
Handles animation timeline and playback.
const animation = useAnimation({
onFrame: (t) => console.log(`Frame t=${t}`)
});useViewportMenus()
Manages viewport context menus and interactions.
useWebSocket(url, options)
WebSocket connection for real-time collaboration.
useResizablePanel(options)
Manages resizable panel state.
Utilities
API Client
import { evaluateCode, parseCode, exportGeometry } from '@moicad/gui/lib';
// Evaluate code to geometry
const result = await evaluateCode('cube(10);', 'openscad');
// Parse code to AST
const ast = await parseCode('sphere(5);');
// Export geometry
await exportGeometry(geometry, 'stl', 'output.stl');Three.js Utilities
import {
createGeometryFromData,
createMeshFromGeometry,
exportToSTL,
exportToOBJ
} from '@moicad/gui/lib';
const threeMesh = createMeshFromGeometry(geometry);
const stlData = exportToSTL(geometry);Animation Utilities
import {
detectAnimation,
renderAnimationFrame,
exportAnimationGIF
} from '@moicad/gui/lib';
const isAnim = detectAnimation(code, language);
const frameGeometry = await renderAnimationFrame(code, 0.5);
await exportAnimationGIF(frames, 'output.gif');Storage Utilities
import {
saveFile,
loadFile,
listFiles,
deleteFile
} from '@moicad/gui/lib';
saveFile('my-model', { code, language });
const file = loadFile('my-model');
const files = listFiles();
deleteFile('my-model');Printer Presets
import { printerPresets, type PrinterPreset } from '@moicad/gui/lib';
const ender3 = printerPresets.find(p => p.name === 'Ender 3');
console.log(ender3.buildVolume); // [220, 220, 250]Usage in @moicad/cli
The @moicad/cli package uses the CADEditor component to provide a full-featured web UI:
# Install CLI
npm install -g @moicad/cli
# Launch web UI (loads CADEditor from @moicad/gui via CDN)
moicadThe CLI:
- Serves a minimal HTML page from
packages/cli/src/server.ts - Uses import maps to load
@moicad/guifrom CDN at runtime - Renders CADEditor to the DOM
- Routes API calls to the local Bun server
This approach keeps the CLI binary lightweight (~1.75 MB) while providing the full-featured GUI.
Architecture Diagram:
Browser
├─ HTML (from CLI server)
├─ React 19.2.4 (esm.sh)
├─ Three.js 0.182.0 (esm.sh)
├─ Monaco 0.55.1 (esm.sh)
├─ @moicad/gui CADEditor (CDN.js)
└─ @moicad/sdk (CDN.js)
Local Bun Server (port 42069)
├─ /api/evaluate
├─ /api/parse
├─ /api/export
└─ /manifold.wasmTheming
Components use Tailwind CSS classes. To customize:
import '@moicad/gui/styles.css'; // If we export styles
// Or provide your own theme
<Editor
className="custom-editor-theme"
theme="vs-dark" // Monaco theme
/>TypeScript
All components, hooks, and utilities are fully typed with TypeScript definitions included.
import type {
EditorRef,
AnimationControlsProps,
FileManagerRef,
GeometryData,
PrinterPreset
} from '@moicad/gui';API Configuration
By default, components expect API endpoints at:
POST /api/evaluate- Code evaluationPOST /api/parse- Code parsingPOST /api/export- Geometry export
Configure custom endpoints:
import { setAPIBaseURL } from '@moicad/gui/lib';
setAPIBaseURL('http://localhost:42069');Browser Support
- Chrome/Edge 90+
- Firefox 88+
- Safari 14+
Requires WebAssembly support for @moicad/sdk.
License
MIT
Links
- GitHub Repository
- Documentation
- Examples
- @moicad/sdk - Core CAD engine
- @moicad/cli - Command-line tool
