superleap-code-editor
Version:
A flexible, reusable code editor component with multiple file handling modes
357 lines (278 loc) • 7.89 kB
Markdown
# @superleap/code-editor
A flexible, reusable React code editor component with multiple file handling modes, built with Monaco Editor and Ant Design.
## Features
- 🚀 **Multiple File Sources**: Support for workflow data, form content, and URL-based files
- 📁 **File Explorer**: Tree-based file navigation with Ant Design components
- 🎨 **Monaco Editor**: Full-featured code editor with syntax highlighting
- 🔧 **Resizable Panels**: Splitter-based layout with collapsible panels
- ⌨️ **Keyboard Shortcuts**: VS Code-like shortcuts (Ctrl+B to toggle panels)
- 🎯 **TypeScript**: Full TypeScript support with type definitions
- 📦 **Tree Shakeable**: Optimized bundle size with tree shaking support
## Installation
```bash
npm install @superleap/code-editor
# or
yarn add @superleap/code-editor
# or
pnpm add @superleap/code-editor
```
## Peer Dependencies
This package requires the following peer dependencies:
```bash
npm install react react-dom antd @monaco-editor/react @tabler/icons-react
```
## Quick Start
### Basic Usage
```tsx
import { CodeEditorWrapper } from '@superleap/code-editor';
import '@superleap/code-editor/styles';
function App() {
const config = {
formConfig: {
codeContent: 'console.log("Hello World!");',
fileName: 'example.js',
language: 'javascript'
}
};
return <CodeEditorWrapper config={config} />;
}
```
## File Handling Modes
### 1. Workflow Mode
For code that's stored with function IDs and versions:
```tsx
import { WorkflowCodeEditor } from '@superleap/code-editor';
function App() {
const fetchFunction = async (functionId: string, version: string) => {
const response = await fetch(`/api/functions/${functionId}/${version}`);
return response.text();
};
const fetchVersionList = async (functionId: string) => {
const response = await fetch(`/api/functions/${functionId}/versions`);
return response.json();
};
return (
<WorkflowCodeEditor
functionId="func-123"
version="2.1.0"
versionList={['1.0.0', '2.0.0', '2.1.0']}
fetchFunction={fetchFunction}
fetchVersionList={fetchVersionList}
/>
);
}
```
### 2. Form Mode
For code stored as strings in form data:
```tsx
import { FormCodeEditor } from '@superleap/code-editor';
function App() {
const [code, setCode] = useState('function example() { return "Hello"; }');
return (
<FormCodeEditor
codeContent={code}
fileName="script.js"
language="javascript"
readOnly={false}
/>
);
}
```
### 3. URL Mode
For files accessible via URLs:
```tsx
import { URLCodeEditor } from '@superleap/code-editor';
function App() {
const fileUrls = [
{
url: 'https://example.com/script.js',
name: 'script.js',
type: 'js'
},
{
url: 'https://example.com/style.css',
name: 'style.css',
type: 'css'
}
];
return <URLCodeEditor fileUrls={fileUrls} />;
}
```
## Advanced Usage
### Custom Configuration
```tsx
import { CodeEditorWrapper } from '@superleap/code-editor';
import type { CodeEditorConfig } from '@superleap/code-editor';
function App() {
const config: CodeEditorConfig = {
workflowConfig: {
functionId: 'my-function',
version: '1.0.0',
versionList: ['1.0.0', '1.1.0'],
fetchFunction: async (id, version) => {
// Your fetch logic
return 'function myFunction() { return "Hello"; }';
},
fetchVersionList: async (id) => {
// Your version fetch logic
return ['1.0.0', '1.1.0'];
}
},
settings: {
readOnly: false,
autoSave: true,
theme: 'vs-light',
fontSize: 14
}
};
return <CodeEditorWrapper config={config} />;
}
```
### Using Individual Components
```tsx
import {
FileExplorer,
CodeEditor,
EditorLayout,
useFileManager,
createFileProvider
} from '@superleap/code-editor';
function CustomEditor() {
const fileProvider = useMemo(() => createFileProvider(config), [config]);
const { files, activeFile, fileContent, setActiveFile, updateFileContent } = useFileManager(fileProvider);
return (
<EditorLayout
leftPanel={
<FileExplorer
files={files}
activeFile={activeFile}
onFileSelect={setActiveFile}
/>
}
editor={
<CodeEditor
value={fileContent}
onChange={updateFileContent}
language="javascript"
/>
}
activePanel="explorer"
setActivePanel={() => {}}
/>
);
}
```
## API Reference
### Components
#### `CodeEditorWrapper`
Main wrapper component that handles all file operations.
**Props:**
- `config: CodeEditorConfig` - Configuration object
- `rightPanel?: React.ReactNode` - Optional right panel content
#### `WorkflowCodeEditor`
Pre-configured component for workflow-based files.
**Props:**
- `functionId: string` - Function identifier
- `version: string` - Current version
- `versionList: string[]` - Available versions
- `fetchFunction: (id: string, version: string) => Promise<string>` - Function to fetch code
- `fetchVersionList: (id: string) => Promise<string[]>` - Function to fetch versions
#### `FormCodeEditor`
Pre-configured component for form-based files.
**Props:**
- `codeContent: string` - Code content
- `fileName?: string` - File name (default: 'code.js')
- `language?: string` - Language for syntax highlighting (default: 'javascript')
- `readOnly?: boolean` - Read-only mode (default: false)
#### `URLCodeEditor`
Pre-configured component for URL-based files.
**Props:**
- `fileUrls: Array<{url: string, name: string, type: string}>` - Array of file URLs
- `rightPanel?: React.ReactNode` - Optional right panel
### Hooks
#### `useFileManager`
Hook for managing file operations.
**Returns:**
- `files: FileNode[]` - File tree
- `activeFile: string | null` - Currently active file ID
- `fileContent: string` - Content of active file
- `loading: boolean` - Loading state
- `error: string | null` - Error state
- `setActiveFile: (fileId: string) => void` - Set active file
- `updateFileContent: (content: string) => void` - Update file content
- `refreshFiles: () => void` - Refresh file list
- `getFileById: (fileId: string) => FileNode | null` - Get file by ID
### Types
#### `CodeEditorConfig`
```typescript
interface CodeEditorConfig {
workflowConfig?: {
functionId: string;
version: string;
versionList: string[];
fetchFunction: (functionId: string, version: string) => Promise<string>;
fetchVersionList: (functionId: string) => Promise<string[]>;
};
formConfig?: {
codeContent: string;
fileName?: string;
language?: string;
};
urlConfig?: {
fileUrls: Array<{
url: string;
name: string;
type: 'js' | 'css' | 'html' | 'json' | 'ts' | 'jsx' | 'tsx';
}>;
};
settings?: {
readOnly?: boolean;
autoSave?: boolean;
theme?: string;
fontSize?: number;
};
}
```
#### `FileNode`
```typescript
interface FileNode {
id: string;
name: string;
type: 'file' | 'folder';
path: string;
content?: string;
children?: FileNode[];
metadata?: {
size?: number;
lastModified?: Date;
language?: string;
url?: string;
};
}
```
## Keyboard Shortcuts
- `Ctrl + B` - Toggle left panel visibility
- `Ctrl + Shift + B` - Toggle right panel visibility
## Styling
The package includes built-in styles. Import them in your app:
```tsx
import '@superleap/code-editor/styles';
```
For custom styling, you can override the CSS classes or use Ant Design's theme customization.
## Development
```bash
# Install dependencies
npm install
# Start development server (demo)
npm run dev
# Build library
npm run build
# Build demo
npm run build:demo
# Lint
npm run lint
```
## License
MIT
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.