npm package: @parent-tobias/chordpro-editor
Description: Lit web component for editing ChordPro formatted songs with Monaco Editor and syntax highlighting
Author: Tobias Parent
Latest version: 1.0.0

# ChordPro Editor

A Lit-based web component that provides a Monaco Editor with ChordPro syntax highlighting. Perfect for editing chord sheets and song lyrics in ChordPro format.

## Features

- Monaco Editor integration with full editing capabilities
- Custom ChordPro syntax highlighting
- Light and dark themes specifically designed for ChordPro
- Configurable editor options (line numbers, minimap, word wrap, etc.)
- Custom events for content changes
- TypeScript support with full type definitions
- CSS custom properties for styling
- Built with Lit for performance and compatibility
- Works with any framework (React, Vue, Angular, Svelte, or vanilla JS)

## Installation

```bash
npm install chordpro-editor
```

## Basic Usage

### In HTML

```html
<!DOCTYPE html>
<html>
<head>
  <script type="module">
    import 'chordpro-editor';
  </script>
</head>
<body>
  <chordpro-editor
    content="{title: Amazing Grace}
{artist: Traditional}

[G]Amazing [C]grace how [G]sweet the sound"
    theme="chordpro-dark"
  ></chordpro-editor>
</body>
</html>
```

### In JavaScript/TypeScript

```javascript
import 'chordpro-editor';

const editor = document.createElement('chordpro-editor');
editor.content = `{title: My Song}
[G]Lyrics with [C]chords`;
editor.theme = 'chordpro-dark';
editor.fontSize = 16;

document.body.appendChild(editor);

// Listen for changes
editor.addEventListener('content-changed', (e) => {
  console.log('New content:', e.detail.content);
});
```

### In React

```jsx
import 'chordpro-editor';

function SongEditor({ initialContent, onChange }) {
  return (
    <chordpro-editor
      content={initialContent}
      theme="chordpro-dark"
      onContent-changed={(e) => onChange(e.detail.content)}
    />
  );
}
```

### In Vue

```vue
<template>
  <chordpro-editor
    :content="songContent"
    theme="chordpro-light"
    :font-size="16"
    @content-changed="handleChange"
  />
</template>

<script setup>
import 'chordpro-editor';
import { ref } from 'vue';

const songContent = ref(`{title: My Song}
[G]Some [C]lyrics`);

const handleChange = (e) => {
  songContent.value = e.detail.content;
};
</script>
```

## Properties

| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `content` | `string` | `''` | The editor content (ChordPro text) |
| `theme` | `string` | `'chordpro-light'` | Editor theme (see themes below) |
| `read-only` | `boolean` | `false` | Whether the editor is read-only |
| `line-numbers` | `boolean` | `true` | Show line numbers |
| `minimap` | `boolean` | `true` | Show minimap |
| `font-size` | `number` | `14` | Font size in pixels |
| `tab-size` | `number` | `2` | Tab size in spaces |
| `word-wrap` | `boolean` | `true` | Enable word wrapping |

### Available Themes

- `chordpro-light` - Light theme optimized for ChordPro (default)
- `chordpro-dark` - Dark theme optimized for ChordPro
- `vs` - Visual Studio light theme
- `vs-dark` - Visual Studio dark theme
- `hc-black` - High contrast theme

## Events

### `content-changed`

Fired when the editor content changes.

```javascript
editor.addEventListener('content-changed', (e) => {
  console.log('Content:', e.detail.content);
});
```

### `editor-ready`

Fired when the Monaco editor instance is initialized.

```javascript
editor.addEventListener('editor-ready', (e) => {
  console.log('Monaco editor:', e.detail.editor);
});
```

## Methods

### `getValue(): string`

Get the current editor content.

```javascript
const content = editor.getValue();
```

### `setValue(value: string): void`

Set the editor content programmatically.

```javascript
editor.setValue('{title: New Song}\n[G]New content');
```

### `getEditor(): monaco.editor.IStandaloneCodeEditor | null`

Get the underlying Monaco editor instance for advanced usage.

```javascript
const monacoEditor = editor.getEditor();
if (monacoEditor) {
  // Use Monaco API directly
  monacoEditor.getPosition();
  monacoEditor.setSelection(...);
}
```

### `focus(): void`

Focus the editor.

```javascript
editor.focus();
```

## ChordPro Syntax Highlighting

The editor provides syntax highlighting for all ChordPro elements:

### Chords
```
[G] [C] [D7] [Em] [A#m7] [D/F#]
```
Chords are highlighted in **blue** (light theme) or **cyan** (dark theme)

### Directives
```
{title: Song Title}
{artist: Artist Name}
{key: G}
{tempo: 120}
{capo: 2}
```
Keywords are highlighted in **red**, values in **blue**

### Sections
```
{start_of_chorus}
{end_of_chorus}
{start_of_verse}
{end_of_verse}
```

### Comments
```
# This is a comment
```
Comments are highlighted in **gray** and italicized

## Styling

The component renders Monaco Editor in the light DOM (Shadow DOM is disabled for Monaco compatibility) and provides CSS custom properties for customization:

```css
chordpro-editor {
  /* Size */
  --editor-height: 600px;
  --editor-width: 100%;

  /* Additional styling */
  display: block;
  border: 1px solid #ddd;
  border-radius: 8px;
}
```

### Available CSS Variables

- `--editor-height` - Height of the editor (default: `400px`)
- `--editor-width` - Width of the editor (default: `100%`)

**Note:** Font size and other editor-specific options should be set via the component properties (e.g., `font-size="16"`) rather than CSS variables.

## Advanced Usage

### Using with chordpro-renderer

Combine with [chordpro-renderer](https://www.npmjs.com/package/chordpro-renderer) for a complete editor + preview experience:

```html
<div style="display: flex; gap: 20px;">
  <chordpro-editor
    id="editor"
    style="flex: 1;"
  ></chordpro-editor>

  <chordpro-renderer
    id="renderer"
    style="flex: 1;"
    show-chords="true"
  ></chordpro-renderer>
</div>

<script>
  const editor = document.getElementById('editor');
  const renderer = document.getElementById('renderer');

  editor.addEventListener('content-changed', (e) => {
    renderer.content = e.detail.content;
  });
</script>
```

### Custom Monaco Configuration

Access the Monaco editor directly for advanced customization:

```javascript
editor.addEventListener('editor-ready', (e) => {
  const monacoEditor = e.detail.editor;

  // Add custom keybinding
  monacoEditor.addCommand(
    monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS,
    () => {
      console.log('Save triggered!');
    }
  );

  // Add custom actions
  monacoEditor.addAction({
    id: 'insert-chorus',
    label: 'Insert Chorus',
    keybindings: [
      monaco.KeyMod.CtrlCmd | monaco.KeyMod.Shift | monaco.KeyCode.KeyC
    ],
    run: (ed) => {
      ed.trigger('keyboard', 'type', {
        text: '{start_of_chorus}\n\n{end_of_chorus}'
      });
    }
  });
});
```

## Browser Support

Modern browsers that support:
- ES2020
- Web Components
- Custom Elements
- Shadow DOM

## Dependencies

- [Lit](https://lit.dev/) - Web component framework
- [Monaco Editor](https://microsoft.github.io/monaco-editor/) - Code editor from VS Code

## Development

```bash
# Install dependencies
npm install

# Run dev server
npm run dev

# Build for production
npm run build

# Preview production build
npm run preview
```

## License

MIT

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## Related Packages

- [chordpro-renderer](https://www.npmjs.com/package/chordpro-renderer) - Render ChordPro songs with chord diagrams