This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This is a monorepo for canvas-editor plugins, managed with Lerna and pnpm workspaces. Each plugin is a separate package under packages/.
# Install dependencies
pnpm install
# Build all packages
pnpm build
# or: lerna run build
# Build single package
cd packages/<name> && pnpm build
# Development mode (runs all packages in dev mode)
pnpm dev
# Type checking
pnpm type:check
# Linting
pnpm lint
# Clean all node_modules
pnpm clean
# Clean all dist folders
pnpm clean:distEach plugin in packages/ follows this structure:
packages/<name>/
├── package.json # Package config with name @hufe921/canvas-editor-plugin-<name>
├── vite.config.ts # Vite config for building (lib mode)
├── tsconfig.json # Extends ../../tsconfig.json
├── src/
│ ├── main.ts # Dev/test entry point
│ └── <name>/
│ ├── index.ts # Main plugin export (default function)
│ ├── index.css # Plugin styles
│ ├── interface/ # TypeScript interfaces
│ └── ...
└── dist/ # Build output
A typical plugin follows this pattern:
import { Editor, EDITOR_COMPONENT, EditorComponent } from '@hufe921/canvas-editor'
import './index.css'
declare module '@hufe921/canvas-editor' {
interface Command {
executePluginName(options?: IPluginOption): void
}
}
class PluginClass {
constructor(options?: IPluginOption) {
// Create dialog/UI
}
private createDialog() {
// Must set attribute for editor integration:
element.setAttribute(EDITOR_COMPONENT, EditorComponent.COMPONENT)
}
}
export default function pluginName(editor: Editor) {
editor.command.executePluginName = (options) => {
new PluginClass(options)
}
}Key patterns:
- Extend
Commandinterface via module declaration - Export default function that receives
Editorinstance - Add command method to
editor.command - Use
EDITOR_COMPONENTandEditorComponent.COMPONENTattributes on UI elements - CSS is injected via
vite-plugin-css-injected-by-js - External dependency:
@hufe921/canvas-editor(not bundled)
Each package uses Vite with lib mode:
- Entry:
src/<name>/index.ts - Output:
dist/<name>.jsanddist/<name>.umd.cjs - Types:
dist/src/<name>/index.d.ts - CSS injected into JS bundle
# 1. Build all packages
pnpm build
# 2. Publish (lerna handles versioning)
pnpm release:publish # from-git
# or
pnpm release:package # from-packagePre-commit runs linting. Commit messages are verified via scripts/verifyCommit.js.
See README.md for list of all plugins and their usage examples.
Key examples:
- diagram: Complex dialog with iframe communication
- specialCharacters: Dialog with category tabs
- menstrualHistory: Custom form layout with fraction display
- case: Simple command without UI (uppercase/lowercase)