@david.uhlir/ide
v0.0.24
Published
IDE Component
Readme
@david.uhlir/ide
A powerful Monaco Editor-based IDE component for React applications with multi-file support, syntax highlighting, diagnostics, and comparison features.
Features
- 🎨 Monaco Editor Integration - Full Monaco Editor functionality with TypeScript support
- 📁 Multi-file Management - Built-in file explorer with add, rename, delete operations
- 🔍 File Comparison - Side-by-side diff view for comparing files
- 🎯 Diagnostics Support - Display TypeScript/ESLint errors and warnings
- 🌓 Theme Support - Light, dark, and auto themes
- 🔄 Change Tracking - Visual indicators for modified, added, and deleted files
- 📝 TypeScript Support - Full IntelliSense and type checking
- 🎛️ Customizable - Configurable footer, confirmation dialogs, and more
Installation
npm install @david.uhlir/idePeer Dependencies
npm install react styled-components monaco-editor @monaco-editor/reactFor webpack-based projects, also install:
npm install monaco-editor-webpack-pluginWebpack Configuration
Add Monaco Editor Webpack Plugin to your webpack config:
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.ttf$/,
type: 'asset/resource',
},
],
},
resolve: {
fallback: {
"path": false,
"fs": false,
"os": false,
"crypto": false,
"buffer": false,
"stream": false,
"util": false,
"assert": false,
"url": false,
"querystring": false,
}
},
output: {
globalObject: 'self',
},
plugins: [
new MonacoWebpackPlugin({
languages: ['javascript', 'typescript', 'json', 'html', 'css', 'markdown'],
features: [
'bracketMatching',
'clipboard',
'coreCommands',
'cursorUndo',
'find',
'folding',
'format',
'hover',
'multicursor',
'suggest'
]
}),
],
};Basic Usage
import React, { useState } from 'react';
import { IDE } from '@david.uhlir/ide';
const files = [
{
filename: '/index.ts',
content: 'console.log("Hello World!");'
},
{
filename: '/utils.ts',
content: 'export const utils = { greeting: "Hello" };'
}
];
function App() {
const [currentFiles, setCurrentFiles] = useState(files);
return (
<div style={{ height: '100vh' }}>
<IDE
files={files}
onChange={setCurrentFiles}
theme="auto"
title="My Code Editor"
/>
</div>
);
}API Reference
IDE Props
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| files | FileItemType[] | required | Array of files to display |
| onChange | (files: FileItemType[]) => void | required | Callback when files change |
| theme | 'light' \| 'dark' \| 'auto' | 'auto' | Editor theme |
| title | React.ReactNode | '' | IDE title displayed in header |
| typings | string[] | [] | TypeScript type definitions |
| diagnostics | MonacoDiagnostic[] | [] | Errors/warnings to display |
| compareWith | FileItemType[] | undefined | Files to compare against |
| onHasChangesChange | (hasChanges: boolean) => void | undefined | Callback when change status updates |
| onCompareDone | () => void | undefined | Callback when comparison is closed |
| onActionConfirm | (message: string) => Promise<boolean> | default confirm | Custom confirmation dialog |
| allowReinit | boolean | false | Allow reinitializing files prop |
| customFooter | React.ReactNode \| ((fullscreen: boolean) => React.ReactNode) | undefined | Custom footer content |
FileItemType
interface FileItemType {
filename: string;
content: string;
oldFilename?: string; // For renamed files
}MonacoDiagnostic
interface MonacoDiagnostic {
category: number;
code: number;
length: number;
messageText: string;
start: number;
}Advanced Examples
With TypeScript Support
import { IDE } from '@david.uhlir/ide';
const typings = [
`declare module "my-module" {
export function myFunction(): string;
}`
];
const files = [
{
filename: '/app.ts',
content: `import { myFunction } from "my-module";
console.log(myFunction());`
}
];
<IDE
files={files}
onChange={setFiles}
typings={typings}
diagnostics={diagnostics}
/>With File Comparison
const originalFiles = [
{ filename: '/config.json', content: '{"version": "1.0.0"}' }
];
const compareFiles = [
{ filename: '/config.json', content: '{"version": "2.0.0"}' }
];
<IDE
files={originalFiles}
onChange={setFiles}
compareWith={compareFiles}
onCompareDone={() => console.log('Comparison closed')}
/>With Custom Footer
<IDE
files={files}
onChange={setFiles}
customFooter={(isFullscreen) => (
<div>
<button onClick={saveFiles}>Save All</button>
<span>Status: {isFullscreen ? 'Fullscreen' : 'Normal'}</span>
</div>
)}
/>With Diagnostics
const diagnostics = [
{
category: 1, // Error
code: 2304,
length: 9,
messageText: "Cannot find name 'undefined_var'.",
start: 45,
}
];
<IDE
files={files}
onChange={setFiles}
diagnostics={diagnostics}
/>Styling
The IDE uses styled-components and respects the system theme by default. You can customize the appearance by:
- Theme Selection: Use
themeprop to force light/dark mode - Custom Styling: The component uses CSS custom properties that can be overridden
- Monaco Themes: Monaco's built-in themes are automatically applied
Development
Running the Example
# Clone the repository
git clone https://github.com/daviduhlir/ide.git
cd ide
# Install dependencies
npm install
# Build the package
npm run build
# Run the example
cd example
npm install
npm startBuilding
npm run build # Build for production
npm run build:watch # Build in watch mode
npm run build:release # Build optimized releaseTesting
npm test # Run all tests (18 tests pass)
npm run test:watch # Run tests in watch mode
npm run test:coverage # Run tests with coverage reportTest Status: ✅ 18/18 tests passing
The project includes tests for:
- ✅ Utility Functions: Path resolution, file extension handling
- ✅ Business Logic: File operations, validation, change detection
- ✅ Conceptual Tests: File type detection, comparison algorithms
Monaco Editor Testing: Component-level tests are disabled (.disabled files) due to Monaco's complexity with Web Workers and browser APIs. This is a common pattern in Monaco-based projects.
Manual Testing: Use cd example && npm start for testing Monaco-specific features.
See Testing Documentation for detailed strategy.
Code Quality
npm run prettier-check # Check code formatting
npm run prettier-format # Format codeBrowser Support
- Chrome/Edge 88+
- Firefox 78+
- Safari 14+
Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
ISC License - see LICENSE file for details.
Changelog
0.0.18
- Current stable release
- Full Monaco Editor integration
- Multi-file support with file explorer
- Comparison view functionality
- TypeScript diagnostics support
