mcpField
S
slidev-monaco-editor

slidev-monaco-editor

github.com/yoanbernabeuドキュメント41209 回インストール39 週間前に更新
リポジトリ

slidev-monaco-editor について

slidev-monaco-editorは、ライブコーディングやインタラクティブなデモ向けにMonaco EditorをSlidevへ組み込むスキルです。編集可能なコードブロック、実行、出力表示、エディター設定を扱います。

主な機能

  1. 01編集可能なMonacoコードブロック
  2. 02JavaScriptとTypeScriptの実行
  3. 03実行結果の表示
  4. 04読み取り専用と差分エディター
  5. 05エディター設定とテーマの構成

活用シーン

  1. 01ライブでコード編集を実演
  2. 02サンプルを実行して出力を確認
  3. 03プログラミング概念の指導
  4. 04インタラクティブなコード演習の作成

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/yoanbernabeu/slidev-skills --skill slidev-monaco-editor

インストール後、Claude Code で/slidev-monaco-editorを入力して読み込まれたか確認します。

詳細

Slidev での Monaco Editor

このスキルでは、VS Code を支えるエディターである Monaco Editor を Slidev プレゼンテーションに統合し、ライブコーディング、インタラクティブなデモ、実行可能なコードブロックに活用する方法を説明します。

このスキルを使う場面

  • ライブコーディングのデモ
  • プレゼンテーション中のインタラクティブなコード編集
  • コード例のリアルタイム実行
  • プログラミングの概念の指導
  • 自動補完と型ヒントの表示

Monaco Editor を有効にする

基本的な Monaco ブロック

任意のコードブロックに {monaco} を追加します。

```typescript {monaco}
const greeting = 'Hello, World!'
console.log(greeting)
```

これにより、次の機能を備えた編集可能なコードブロックが作成されます。

  • 構文の強調表示
  • 自動補完
  • 型チェック(TypeScript の場合)
  • 括弧の対応付け
行の強調表示を使う Monaco
```typescript {monaco}{2,3}
const a = 1
const b = 2  // highlighted
const c = 3  // highlighted
```

Monaco Runner

プレゼンテーション内でコードを直接実行します。

JavaScript Runner
```javascript {monaco-run}
const numbers = [1, 2, 3, 4, 5]
const doubled = numbers.map(n => n * 2)
console.log(doubled)
```

「Run」をクリックすると、コードが実行され、出力が表示されます。

TypeScript Runner
```typescript {monaco-run}
interface User {
  name: string
  age: number
}

const user: User = {
  name: 'John',
  age: 30
}

console.log(`${user.name} is ${user.age} years old`)
```
読み込み時に自動実行
```javascript {monaco-run} {autorun:true}
console.log('This runs automatically!')
```
出力のみを表示
```javascript {monaco-run} {showOutputAt:'+1'}
// Output shows after one click
console.log('Hello!')
```

設定オプション

エディターの高さ
```typescript {monaco}{height:'300px'}
// Taller editor
function longFunction() {
  // ...
}
```
読み取り専用モード
```typescript {monaco}{readonly:true}
// Cannot be edited
const CONSTANT = 'value'
```
差分エディター
```typescript {monaco-diff}
const original = 'Hello'
~~~
const modified = 'Hello, World!'
```

Monaco のセットアップ設定

setup/monaco.ts
import { defineMonacoSetup } from '@slidev/types'

export default defineMonacoSetup((monaco) => {
  // Editor options
  return {
    editorOptions: {
      fontSize: 14,
      fontFamily: 'JetBrains Mono, monospace',
      minimap: { enabled: false },
      lineNumbers: 'on',
      wordWrap: 'on',
      tabSize: 2,
      scrollBeyondLastLine: false,
      automaticLayout: true,
    },
    // Light/dark theme
    theme: {
      light: 'vs',
      dark: 'vs-dark',
    },
  }
})
カスタムテーマ
import { defineMonacoSetup } from '@slidev/types'

export default defineMonacoSetup((monaco) => {
  // Define custom theme
  monaco.editor.defineTheme('my-theme', {
    base: 'vs-dark',
    inherit: true,
    rules: [
      { token: 'comment', foreground: '6A9955' },
      { token: 'keyword', foreground: 'C586C0' },
    ],
    colors: {
      'editor.background': '#1a1a2e',
    },
  })

  return {
    theme: {
      dark: 'my-theme',
      light: 'vs',
    },
  }
})

型定義

ライブラリの型を追加する
// setup/monaco.ts
import { defineMonacoSetup } from '@slidev/types'

export default defineMonacoSetup(async (monaco) => {
  // Add React types
  const reactTypes = await fetch(
    'https://unpkg.com/@types/react/index.d.ts'
  ).then(r => r.text())

  monaco.languages.typescript.typescriptDefaults.addExtraLib(
    reactTypes,
    'file:///node_modules/@types/react/index.d.ts'
  )
})
インライン型定義
```typescript {monaco}
// Types defined inline
interface Todo {
  id: number
  text: string
  completed: boolean
}

const todos: Todo[] = [
  { id: 1, text: 'Learn Slidev', completed: true },
  { id: 2, text: 'Create presentation', completed: false },
]
```

インタラクティブな例

カウンターのデモ
```typescript {monaco-run}
// Interactive counter
let count = 0

function increment() {
  count++
  console.log(`Count: ${count}`)
}

// Click Run multiple times!
increment()
```
API のシミュレーション
```typescript {monaco-run}
// Simulated API call
async function fetchUser(id: number) {
  // Simulate network delay
  await new Promise(r => setTimeout(r, 500))

  return {
    id,
    name: 'John Doe',
    email: '[email protected]'
  }
}

const user = await fetchUser(1)
console.log(user)
```
アルゴリズムの可視化
```typescript {monaco-run}
// Bubble sort with steps
function bubbleSort(arr: number[]) {
  const result = [...arr]
  const steps: string[] = []

  for (let i = 0; i < result.length; i++) {
    for (let j = 0; j < result.length - i - 1; j++) {
      if (result[j] > result[j + 1]) {
        [result[j], result[j + 1]] = [result[j + 1], result[j]]
        steps.push(`Swap: [${result.join(', ')}]`)
      }
    }
  }

  return { result, steps }
}

const { result, steps } = bubbleSort([5, 3, 8, 4, 2])
console.log('Steps:', steps.length)
steps.forEach(s => console.log(s))
console.log('Final:', result)
```

コードランナーのパターン

概念を示してから編集してもらう
# Array Methods

```typescript {monaco-run}
const numbers = [1, 2, 3, 4, 5]

// Try changing the function!
const result = numbers
  .filter(n => n % 2 === 0)
  .map(n => n * 2)

console.log(result)
```

Try modifying the code to:
- Filter odd numbers
- Triple instead of double
インタラクティブなクイズ
# Fix the Bug

```typescript {monaco-run}
// This code has a bug - can you fix it?
function reverseString(str: string) {
  return str.split('').reserve().join('')
}

console.log(reverseString('hello'))
// Expected: 'olleh'
```
ライブデータの操作
```typescript {monaco-run}
const data = [
  { name: 'Alice', score: 85 },
  { name: 'Bob', score: 92 },
  { name: 'Charlie', score: 78 },
]

// Calculate statistics
const average = data.reduce((sum, d) => sum + d.score, 0) / data.length
const highest = Math.max(...data.map(d => d.score))
const passing = data.filter(d => d.score >= 80)

console.log(`Average: ${average.toFixed(1)}`)
console.log(`Highest: ${highest}`)
console.log(`Passing: ${passing.map(d => d.name).join(', ')}`)
```

アニメーションとの組み合わせ

表示してから編集する
<v-click>

```typescript {monaco}
// Code appears on click, then is editable
function greet(name: string) {
  return `Hello, ${name}!`
}
```

</v-click>
Monaco を使ったステップごとの説明
<v-clicks>

Start with this code:

```typescript {monaco}
const x = 1
```

Then try adding more lines!

</v-clicks>

ベストプラクティス

1. 例の焦点を絞る
```typescript {monaco-run}
// GOOD: Single concept
const sum = [1, 2, 3].reduce((a, b) => a + b, 0)
console.log(sum) // 6
```
2. 開始地点を用意する
```typescript {monaco-run}
// Complete the function:
function capitalize(str: string): string {
  // Your code here
  return str
}

console.log(capitalize('hello')) // Should print: 'Hello'
```
3. 期待される出力を示す
```typescript {monaco-run}
// Code example
const result = [1, 2, 3].map(n => n ** 2)
console.log(result)
// Expected output: [1, 4, 9]
```
4. エラーに適切に対処する
```typescript {monaco-run}
try {
  const result = riskyOperation()
  console.log(result)
} catch (error) {
  console.error('Error:', error.message)
}

function riskyOperation() {
  // Might throw an error
  throw new Error('Oops!')
}
```

制限事項

  • DOM にアクセスできない: ページの DOM を操作できません
  • 利用できる API が限られている: 標準の JavaScript API のみ利用できます
  • インポートできない: 外部パッケージをインポートできません
  • コンソールのみ: 出力はコンソール上に表示されます

出力形式

Monaco のコードブロックを作成する場合:

PURPOSE: [What the code demonstrates]
INTERACTION: [How audience should interact]

CODE:
```[language] {monaco-run}
// Clear comments explaining purpose

[Code with good defaults]

// Expected output noted

提案する編集:

  • X を Y に変更してみる
  • 関数を変更して Z を実行する

コメント