ds-markdown 0.1.1 → 0.1.2-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ja.md CHANGED
@@ -20,39 +20,30 @@
20
20
 
21
21
  ## ✨ コア機能
22
22
 
23
- ### 🎯 **完璧な再現**
23
+ ### 🤖 **AI 会話シナリオ**
24
24
 
25
25
  - [DeepSeek ウェブサイト](https://chat.deepseek.com/) のチャット応答効果を1:1で再現
26
26
  - 思考プロセス(`thinking`)と回答内容(`answer`)の両方のモードをサポート
27
- - コードハイライト、テーブル、リストなどを含むネイティブMarkdown構文サポート
28
- - ライト/ダークテーマのサポート、様々なシナリオに完璧に対応
27
+ - ストリーミングデータに完璧に対応、ユーザー入力への遅延ゼロ応答
29
28
 
30
- ### **究極のパフォーマンス**
29
+ ### 📊 **コンテンツ表示シナリオ**
31
30
 
32
- - スマートバッチ処理により、大容量ドキュメントでもラグゼロレンダリング
33
- - デュアルタイマーモード:`requestAnimationFrame` + `setTimeout`
34
- - 内蔵ストリーミング構文バッファリングで、不完全な Markdown レンダリングエラーを回避
31
+ - コードハイライト、テーブル、リストなどを含む完全な Markdown 構文サポート
32
+ - 数式レンダリング (KaTeX)、`$...$` と `\[...\]` 構文をサポート
33
+ - ライト/ダークテーマサポート、様々なプロダクトスタイルに対応
34
+ - remark/rehype プラグイン拡張をサポートするプラグインアーキテクチャ
35
35
 
36
- ### 🎬 **滑らかなアニメーション**
36
+ ### �� **開発者エクスペリエンス**
37
37
 
38
- - 高頻度タイピングサポート(`requestAnimationFrame` モードでは `0ms` に近いタイピング間隔をサポート)
39
- - フレーム同期レンダリング、ブラウザの 60fps と完璧にマッチ
40
- - スマート文字バッチ処理により、より自然な視覚効果
41
38
  - タイピングの中断 `stop` と再開 `resume` をサポート
39
+ - タイピングの無効化と有効化をサポート
42
40
 
43
- ### 🔧 **柔軟で使いやすい**
44
-
45
- - **宣言的 API**:シンプルなシナリオに適し、React スタイル
46
- - **命令的 API**:ストリーミングデータに適し、より良いパフォーマンス
47
- - **ネイティブ TypeScript サポート**:完全な型ヒント
48
-
49
- ### 🧮 **数式サポート**
41
+ ### 🎬 **滑らかなアニメーション**
50
42
 
51
- - **KaTeX 統合**:高性能な数式レンダリング
52
- - **プラグインアーキテクチャ**:プラグインシステムによる柔軟な設定
53
- - **デュアル構文サポート**:`$...$` と `\[...\]` の2つの区切り文字
54
- - **ストリーミング対応**:タイピングアニメーションでの数式の完璧なサポート
55
- - **テーマ適応**:ライト/ダークテーマへの自動適応
43
+ - デュアルタイマーモード最適化、`requestAnimationFrame` と `setTimeout` モードをサポート
44
+ - 高頻度タイピングサポート(`requestAnimationFrame` モードでは `0ms` に近いタイピング間隔をサポート)
45
+ - フレーム同期レンダリング、ブラウザのリフレッシュレートと完璧にマッチ
46
+ - スマート文字バッチ処理により、より自然な視覚効果
56
47
 
57
48
  ---
58
49
 
@@ -76,8 +67,10 @@ pnpm add ds-markdown
76
67
  [DEMO](https://stackblitz.com/edit/stackblitz-starters-7vcclcw7?file=index.html)
77
68
 
78
69
  ```html
79
- <!-- スタイルのインポート -->
70
+ <!-- スタイルのインポート、必須 -->
80
71
  <link rel="stylesheet" href="https://esm.sh/ds-markdown/dist/style.css" />
72
+
73
+ <!-- katex数学公式スタイルのインポート、必要な場合のみ -->
81
74
  <link rel="stylesheet" href="https://esm.sh/ds-markdown/dist/katex.css" />
82
75
 
83
76
  <!-- コンポーネントのインポート -->
@@ -105,18 +98,42 @@ function App() {
105
98
  }
106
99
  ```
107
100
 
101
+ ### タイピングアニメーションの無効化
102
+
103
+ ```tsx
104
+ import DsMarkdown from 'ds-markdown';
105
+ import 'ds-markdown/style.css';
106
+
107
+ function StaticDemo() {
108
+ const [disableTyping, setDisableTyping] = useState(false);
109
+
110
+ return (
111
+ <div>
112
+ <button onClick={() => setDisableTyping(!disableTyping)}>{disableTyping ? '有効' : '無効'}にするタイピング効果</button>
113
+
114
+ <DsMarkdown interval={20} answerType="answer" disableTyping={disableTyping}>
115
+ # 静的表示モード `disableTyping` が `true` の場合、コンテンツはタイピングアニメーション効果なしで即座に全て表示されます。これは特定のシナリオで非常に有用です: - 📄 静的ドキュメント表示 - 🔄
116
+ 表示モードの切り替え - ⚡ コンテンツの素早いプレビュー
117
+ </DsMarkdown>
118
+ </div>
119
+ );
120
+ }
121
+ ```
122
+
108
123
  ### 数式サポート
109
124
 
110
125
  ```tsx
111
126
  import DsMarkdown from 'ds-markdown';
127
+ // 数式を表示する必要がある場合は、数式変換プラグインを取り込む
112
128
  import { katexPlugin } from 'ds-markdown/plugins';
113
129
  import 'ds-markdown/style.css';
114
- import 'ds-markdown/katex.css'; // 数式スタイルのインポート
130
+ // 数式を表示する必要がある場合は、数学公式スタイルを取り込む
131
+ import 'ds-markdown/katex.css';
115
132
 
116
133
  function MathDemo() {
117
134
  return (
118
135
  <DsMarkdown interval={20} answerType="answer" plugins={[katexPlugin]} math={{ splitSymbol: 'dollar' }}>
119
- # ピタゴラスの定理 直角三角形では、斜辺の二乗は二つの直角辺の二乗の和に等しい: $a^2 + b^2 = c^2$ ここで: - $a$ と $b$ は直角辺 - $c$ は斜辺 古典的な「3-4-5」三角形の場合: $c = \sqrt
136
+ # ピタゴラスの定理 直角三角形では、斜辺の二乗は二つの直角辺の二乗の和に等しい: $a^2 + b^2 = c^2$ ここで: - $a$ と $b$ は直角辺 - $c$ は斜辺 古典的な「勾三股四弦五」の場合: $c = \sqrt
120
137
  {3 ^ (2 + 4) ^ 2} = \sqrt{25} = 5$
121
138
  </DsMarkdown>
122
139
  );
@@ -171,40 +188,73 @@ React 19 は多くのエキサイティングな新機能をもたらします
171
188
 
172
189
  ## 📚 完全 API ドキュメント
173
190
 
174
- ### 宣言的 API(初心者向け推奨)
191
+ ### デフォルトエクスポート DsMarkdown と MarkdownCMD の props
192
+
193
+ ```js
194
+ import DsMarkdown, { MarkdownCMD } from 'ds-markdown';
195
+ ```
196
+
197
+ | プロパティ | 型 | 説明 | デフォルト |
198
+ | --------------- | --------------------------------------------- | ---------------------------------- | --------------------------------------------------------------------- |
199
+ | `interval` | `number` | タイピング間隔(ミリ秒) | `30` |
200
+ | `timerType` | `'setTimeout'` \| `'requestAnimationFrame'` | タイマータイプ | 現在のデフォルトは`setTimeout`、後で`requestAnimationFrame`に変更予定 |
201
+ | `answerType` | `'thinking'` \| `'answer'` | コンテンツタイプ(スタイルに影響) | `'answer'` |
202
+ | `theme` | `'light'` \| `'dark'` | テーマタイプ | `'light'` |
203
+ | `plugins` | `IMarkdownPlugin[]` | プラグイン設定 | `[]` |
204
+ | `math` | [IMarkdownMath](#IMarkdownMath) | 数式設定 | `{ splitSymbol: 'dollar' }` |
205
+ | `onEnd` | `(data: EndData) => void` | タイピング完了コールバック | - |
206
+ | `onStart` | `(data: StartData) => void` | タイピング開始コールバック | - |
207
+ | `onTypedChar` | `(data: `[ITypedChar](#ITypedChar)`) => void` | 文字ごとのタイピングコールバック | - |
208
+ | `disableTyping` | `boolean` | タイピングアニメーション効果を無効 | `false` |
209
+
210
+ > 注意: タイピング中に `disableTyping` が `true` から `false` に変わると、次のタイピングトリガー時に残りの全文字が一度に表示されます。
175
211
 
176
- | プロパティ | 型 | 説明 | デフォルト |
177
- | ------------- | ------------------------------------------- | -------------------------------- | --------------------------------------------------------------------- |
178
- | `interval` | `number` | タイピング間隔(ミリ秒) | `30` |
179
- | `timerType` | `'setTimeout'` \| `'requestAnimationFrame'` | タイマータイプ | 現在のデフォルトは`setTimeout`、後で`requestAnimationFrame`に変更予定 |
180
- | `answerType` | `'thinking'` \| `'answer'` | コンテンツタイプ | `'answer'` |
181
- | `theme` | `'light'` \| `'dark'` | テーマタイプ | `'light'` |
182
- | `math` | `IMarkdownMath` | 数式設定 | `{ isOpen: false, splitSymbol: 'dollar' }` |
183
- | `onEnd` | `(data: EndData) => void` | タイピング完了コールバック | - |
184
- | `onStart` | `(data: StartData) => void` | タイピング開始コールバック | - |
185
- | `onTypedChar` | `(data: CharData) => void` | 文字ごとのタイピングコールバック | - |
212
+ ### ITypedChar
186
213
 
187
- ### 数式設定
214
+ | プロパティ | 型 | 説明 | デフォルト |
215
+ | -------------- | -------- | -------------------------------- | ---------- |
216
+ | `percent` | `number` | タイピング進行パーセンテージ | `0` |
217
+ | `currentChar` | `string` | 現在タイピング中の文字 | - |
218
+ | `currentIndex` | `number` | 文字列全体での現在のインデックス | `0` |
188
219
 
189
- | プロパティ | 型 | 説明 | デフォルト |
190
- | ------------- | ------------------------- | ---------------------------- | ---------- |
191
- | `isOpen` | `boolean` | 数式レンダリングを有効にする | `false` |
192
- | `splitSymbol` | `'dollar'` \| `'bracket'` | 数式区切り文字タイプ | `'dollar'` |
220
+ #### IMarkdownMath
221
+
222
+ | プロパティ | 型 | 説明 | デフォルト |
223
+ | ------------- | ------------------------- | -------------------- | ---------- |
224
+ | `splitSymbol` | `'dollar'` \| `'bracket'` | 数式区切り文字タイプ | `'dollar'` |
193
225
 
194
226
  **区切り文字の説明:**
195
227
 
196
228
  - `'dollar'`:`$...$` と `$$...$$` 構文を使用
197
229
  - `'bracket'`:`\(...\)` と `\[...\]` 構文を使用
198
230
 
199
- ### 命令的 API(ストリーミングシナリオにおすすめ)
231
+ #### IMarkdownPlugin
232
+
233
+ | プロパティ | 型 | 説明 | デフォルト |
234
+ | -------------- | ------------------------- | ----------------- | ---------- |
235
+ | `remarkPlugin` | `unknown` | remark プラグイン | - |
236
+ | `rehypePlugin` | `unknown` | rehype プラグイン | - |
237
+ | `type` | `'buildIn'` \| `'custom'` | プラグインタイプ | - |
238
+ | `id` | `any` | プラグイン固有ID | - |
239
+
240
+ ### コンポーネント公開メソッド
241
+
242
+ #### デフォルトエクスポート DsMarkdown
243
+
244
+ | メソッド | パラメータ | 説明 |
245
+ | -------- | ---------- | -------------------- |
246
+ | `stop` | - | タイピングを一時停止 |
247
+ | `resume` | - | タイピングを再開 |
200
248
 
201
- | メソッド | パラメータ | 説明 |
202
- | ----------------- | ------------------------------------------- | ------------------------------------ |
203
- | `push` | `(content: string, answerType: AnswerType)` | コンテンツを追加してタイピングを開始 |
204
- | `clear` | - | すべてのコンテンツと状態をクリア |
205
- | `triggerWholeEnd` | - | 完了コールバックを手動でトリガー |
206
- | `stop` | - | タイピングを一時停止 |
207
- | `resume` | - | タイピングを再開 |
249
+ #### MarkdownCMD 公開メソッド
250
+
251
+ | メソッド | パラメータ | 説明 |
252
+ | ----------------- | ------------------------------------------- | ---------------------------------- |
253
+ | `push` | `(content: string, answerType: AnswerType)` | コンテンツを追加してタイピング開始 |
254
+ | `clear` | - | 全コンテンツと状態をクリア |
255
+ | `triggerWholeEnd` | - | 手動で完了コールバックを発火 |
256
+ | `stop` | - | タイピングを一時停止 |
257
+ | `resume` | - | タイピングを再開 |
208
258
 
209
259
  **使用例:**
210
260
 
@@ -217,11 +267,17 @@ markdownRef.current?.resume(); // アニメーションを再開
217
267
 
218
268
  ## 🧮 数式使用ガイド
219
269
 
270
+ [DEMO1:ピタゴラスの定理](https://stackblitz.com/edit/vitejs-vite-z94syu8j?file=src%2FApp.tsx)
271
+
272
+ [DEMO2:問題解答](https://stackblitz.com/edit/vitejs-vite-xk9lxagc?file=README.md)
273
+
220
274
  ### 基本構文
221
275
 
222
276
  ```tsx
223
- // 1. 数式サポートを有効にする
224
- <DsMarkdown math={{ isOpen: true }}>
277
+ import { katexPlugin } from 'ds-markdown/plugins';
278
+
279
+ // 1. 数式サポートを有効化
280
+ <DsMarkdown plugins={[katexPlugin]}>
225
281
  # 数式の例
226
282
 
227
283
  // インライン数式
@@ -236,13 +292,19 @@ markdownRef.current?.resume(); // アニメーションを再開
236
292
 
237
293
  ```tsx
238
294
  // ドル記号区切り文字を使用(デフォルト)
239
- <DsMarkdown math={{ isOpen: true, splitSymbol: 'dollar' }}>
295
+ <DsMarkdown
296
+ plugins={[katexPlugin]}
297
+ math={{ splitSymbol: 'dollar' }}
298
+ >
240
299
  インライン:$a + b = c$
241
300
  ブロック:$$\sum_{i=1}^{n} x_i = x_1 + x_2 + \cdots + x_n$$
242
301
  </DsMarkdown>
243
302
 
244
303
  // 括弧区切り文字を使用
245
- <DsMarkdown math={{ isOpen: true, splitSymbol: 'bracket' }}>
304
+ <DsMarkdown
305
+ plugins={[katexPlugin]}
306
+ math={{ splitSymbol: 'bracket' }}
307
+ >
246
308
  インライン:\(a + b = c\)
247
309
  ブロック:\[\sum_{i=1}^{n} x_i = x_1 + x_2 + \cdots + x_n\]
248
310
  </DsMarkdown>
@@ -251,8 +313,18 @@ markdownRef.current?.resume(); // アニメーションを再開
251
313
  ### ストリーミング数式
252
314
 
253
315
  ```tsx
254
- // ストリーミング出力での数式の完璧なサポート
255
- const mathContent = ['ピタゴラスの定理:', '$a^2 + b^2 = c^2$', '\n\n', 'ここで:', '- $a$ と $b$ は直角辺', '- $c$ は斜辺'];
316
+ // ストリーミング出力での数式を完璧にサポート
317
+ const mathContent = [
318
+ 'ピタゴラスの定理:',
319
+ '$a^2 + b^2 = c^2$',
320
+ '\n\n',
321
+ 'ここで:',
322
+ '- $a$ と $b$ は直角辺\n',
323
+ '- $c$ は斜辺\n\n',
324
+ '古典的な「勾三股四弦五」の場合:\n',
325
+ '$c = \\sqrt{3^2 + 4^2} = \\sqrt{25} = 5$\n\n',
326
+ 'この定理は幾何学で広く応用されています!',
327
+ ];
256
328
 
257
329
  mathContent.forEach((chunk) => {
258
330
  markdownRef.current?.push(chunk, 'answer');
@@ -262,7 +334,7 @@ mathContent.forEach((chunk) => {
262
334
  ### スタイルカスタマイズ
263
335
 
264
336
  ```css
265
- /* 数式スタイルのカスタマイズ */
337
+ /* 数式スタイルカスタマイズ */
266
338
  .katex {
267
339
  font-size: 1.1em;
268
340
  }
@@ -272,7 +344,7 @@ mathContent.forEach((chunk) => {
272
344
  text-align: center;
273
345
  }
274
346
 
275
- /* ダークテーマ適応 */
347
+ /* ダークテーマ対応 */
276
348
  [data-theme='dark'] .katex {
277
349
  color: #e1e1e1;
278
350
  }
@@ -280,54 +352,85 @@ mathContent.forEach((chunk) => {
280
352
 
281
353
  ---
282
354
 
355
+ ## 🔌 プラグインシステム
356
+
357
+ ### 内蔵プラグイン
358
+
359
+ #### KaTeX 数式プラグイン
360
+
361
+ ```tsx
362
+ import { katexPlugin } from 'ds-markdown/plugins';
363
+
364
+ // 数式サポートを有効化
365
+ <DsMarkdown plugins={[katexPlugin]}>数式:$E = mc^2$</DsMarkdown>;
366
+ ```
367
+
368
+ ### カスタムプラグイン
369
+
370
+ ```tsx
371
+ import { createBuildInPlugin } from 'ds-markdown/plugins';
372
+
373
+ // カスタムプラグインを作成
374
+ const customPlugin = createBuildInPlugin({
375
+ remarkPlugin: yourRemarkPlugin,
376
+ rehypePlugin: yourRehypePlugin,
377
+ id: Symbol('custom-plugin'),
378
+ });
379
+
380
+ // カスタムプラグインを使用
381
+ <DsMarkdown plugins={[katexPlugin, customPlugin]}>コンテンツ</DsMarkdown>;
382
+ ```
383
+
384
+ ---
385
+
283
386
  ## 🎛️ タイマーモード詳細
284
387
 
285
- ### `requestAnimationFrame` モード 🌟(推奨)
388
+ ### `requestAnimationFrame` モード 🌟 (推奨)
286
389
 
287
390
  ```typescript
288
391
  // 🎯 特徴
289
392
  - 時間駆動:実際の経過時間に基づいて文字数を計算
290
- - バッチ処理:1フレーム内で複数の文字を処理可能
393
+ - バッチ処理:単一フレーム内で複数文字を処理可能
291
394
  - フレーム同期:ブラウザの60fpsリフレッシュレートと同期
292
395
  - 高頻度最適化:interval < 16msの高速タイピングを完璧にサポート
293
396
 
294
397
  // 🎯 適用シナリオ
295
398
  - モダンWebアプリケーションのデフォルト選択
296
- - 滑らかなアニメーション効果を追求
297
- - 高頻度タイピング(interval > 0で十分)
298
- - AIリアルタイム会話シナリオ
399
+ - 滑らかなアニメーション効果の追求
400
+ - 高頻度タイピング (interval > 0 で十分)
401
+ - AI リアルタイム会話シナリオ
299
402
  ```
300
403
 
301
- ### `setTimeout` モード 📟(互換性)
404
+ ### `setTimeout` モード 📟 (互換)
302
405
 
303
406
  ```typescript
304
407
  // 🎯 特徴
305
- - 単一文字:毎回正確に1文字を処理
306
- - 固定間隔:設定された時間に厳密に実行
307
- - ビート感:クラシックタイプライターのリズム感
408
+ - 単一文字:毎回正確に一文字を処理
409
+ - 固定間隔:設定時間通りに厳密実行
410
+ - リズム感:クラシックタイプライターのリズム感
308
411
  - 精密制御:特定のタイミング要件に適している
309
412
 
310
413
  // 🎯 適用シナリオ
311
414
  - 精密な時間制御が必要
312
- - レトロタイプライター効果を演出
313
- - 互換性要件の高いシナリオ
415
+ - レトロタイプライター効果の創出
416
+ - 互換性要件が高いシナリオ
314
417
  ```
315
418
 
316
419
  ### 📊 パフォーマンス比較
317
420
 
318
- | 特徴 | requestAnimationFrame | setTimeout |
319
- | -------------------------------- | ----------------------------------- | ----------------- |
320
- | **文字処理** | 1フレームで複数文字を処理可能 | 毎回1文字を処理 |
321
- | **高頻度間隔** | ✅ 優秀(5ms → 1フレーム3文字) | ❌ ラグの可能性 |
322
- | **低頻度間隔** | ✅ 正常(100ms → 6フレーム後1文字) | ✅ 精密 |
323
- | **視覚効果** | 🎬 滑らかなアニメーション感 | ⚡ 精密なビート感 |
324
- | **パフォーマンスオーバーヘッド** | 🟢 低(フレーム同期) | 🟡 中(タイマー) |
421
+ | 特徴 | requestAnimationFrame | setTimeout |
422
+ | -------------------------------- | ----------------------------------- | -------------------- |
423
+ | **文字処理** | フレームあたり複数文字 | 一度に一文字 |
424
+ | **高頻度間隔** | ✅ 優秀 (5ms → フレームあたり3文字) | ❌ ラグ可能性あり |
425
+ | **低頻度間隔** | ✅ 正常 (100ms → 6フレーム後1文字) | ✅ 精密 |
426
+ | **視覚効果** | 🎬 滑らかなアニメーション感 | ⚡ 精密なリズム感 |
427
+ | **パフォーマンスオーバーヘッド** | 🟢 低 (フレーム同期) | 🟡 中程度 (タイマー) |
325
428
 
326
- 高頻度は`requestAnimationFrame`、低頻度は`setTimeout`を推奨
429
+ 高頻度は `requestAnimationFrame` 推奨、低頻度は `setTimeout` 推奨
327
430
 
328
431
  ---
329
432
 
330
- ## 💡 実践例
433
+ ## 💡 実戦例
331
434
 
332
435
  ### 📝 AI ストリーミング会話
333
436
 
@@ -340,25 +443,25 @@ import { MarkdownCMD, MarkdownCMDRef } from 'ds-markdown';
340
443
  function StreamingChat() {
341
444
  const markdownRef = useRef<MarkdownCMDRef>(null);
342
445
 
343
- // AI ストリーミング応答をシミュレート
446
+ // AI ストリーミング応答のシミュレート
344
447
  const simulateAIResponse = async () => {
345
448
  markdownRef.current?.clear();
346
449
 
347
450
  // 思考段階
348
- markdownRef.current?.push('🤔 あなたの質問を分析しています...', 'thinking');
451
+ markdownRef.current?.push('🤔 あなたの質問を分析中...', 'thinking');
349
452
  await delay(1000);
350
- markdownRef.current?.push('\n\n✅ 分析完了、回答を開始', 'thinking');
453
+ markdownRef.current?.push('\n\n✅ 分析完了、回答開始', 'thinking');
351
454
 
352
455
  // ストリーミング回答
353
456
  const chunks = [
354
457
  '# React 19 新機能解析\n\n',
355
458
  '## 🚀 React Compiler\n',
356
- 'React 19 の最大のハイライトは**React Compiler**の導入です:\n\n',
357
- '- 🎯 **自動最適化**:手動のmemouseMemoが不要\n',
358
- '- ⚡ **パフォーマンス向上**:コンパイル時最適化、実行時ゼロオーバーヘッド\n',
459
+ 'React 19 の最大のハイライトは **React Compiler** の導入です:\n\n',
460
+ '- 🎯 **自動最適化**:手動でのmemouseMemoが不要\n',
461
+ '- ⚡ **パフォーマンス向上**:コンパイル時最適化、ランタイムゼロオーバーヘッド\n',
359
462
  '- 🔧 **後方互換性**:既存コードの修正不要\n\n',
360
- '## 📝 Actions フォーム簡素化\n',
361
- '新しいActions APIによりフォーム処理がより簡単になります:\n\n',
463
+ '## 📝 Actions でフォーム簡素化\n',
464
+ '新しい Actions API でフォーム処理がより簡単に:\n\n',
362
465
  '```tsx\n',
363
466
  'function ContactForm({ action }) {\n',
364
467
  ' const [state, formAction] = useActionState(action, null);\n',
@@ -370,7 +473,7 @@ function StreamingChat() {
370
473
  ' );\n',
371
474
  '}\n',
372
475
  '```\n\n',
373
- 'この回答がお役に立てば幸いです!🎉',
476
+ 'この回答がお役に立てれば幸いです!🎉',
374
477
  ];
375
478
 
376
479
  for (const chunk of chunks) {
@@ -383,7 +486,7 @@ function StreamingChat() {
383
486
  <div className="chat-container">
384
487
  <button onClick={simulateAIResponse}>🤖 React 19 新機能について質問</button>
385
488
 
386
- <MarkdownCMD ref={markdownRef} interval={10} timerType="requestAnimationFrame" onEnd={(data) => console.log('段落完了:', data)} />
489
+ <MarkdownCMD ref={markdownRef} interval={10} timerType="requestAnimationFrame" onEnd={(data) => console.log('セクション完了:', data)} />
387
490
  </div>
388
491
  );
389
492
  }
@@ -394,6 +497,8 @@ const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
394
497
  ### 🧮 数式ストリーミングレンダリング
395
498
 
396
499
  ```tsx
500
+ import { katexPlugin } from 'ds-markdown/plugins';
501
+
397
502
  function MathStreamingDemo() {
398
503
  const markdownRef = useRef<MarkdownCMDRef>(null);
399
504
 
@@ -401,13 +506,13 @@ function MathStreamingDemo() {
401
506
  markdownRef.current?.clear();
402
507
 
403
508
  const mathChunks = [
404
- '# ピタゴラスの定理の説明\n\n',
509
+ '# ピタゴラスの定理詳解\n\n',
405
510
  '直角三角形では、斜辺の二乗は二つの直角辺の二乗の和に等しい:\n\n',
406
511
  '$a^2 + b^2 = c^2$\n\n',
407
512
  'ここで:\n',
408
513
  '- $a$ と $b$ は直角辺\n',
409
514
  '- $c$ は斜辺\n\n',
410
- '古典的な「3-4-5」三角形の場合:\n',
515
+ '古典的な「勾三股四弦五」の場合:\n',
411
516
  '$c = \\sqrt{3^2 + 4^2} = \\sqrt{25} = 5$\n\n',
412
517
  'この定理は幾何学で広く応用されています!',
413
518
  ];
@@ -422,70 +527,12 @@ function MathStreamingDemo() {
422
527
  <div>
423
528
  <button onClick={simulateMathResponse}>📐 ピタゴラスの定理を説明</button>
424
529
 
425
- <MarkdownCMD ref={markdownRef} interval={20} timerType="requestAnimationFrame" math={{ isOpen: true, splitSymbol: 'dollar' }} />
530
+ <MarkdownCMD ref={markdownRef} interval={20} timerType="requestAnimationFrame" plugins={[katexPlugin]} math={{ splitSymbol: 'dollar' }} />
426
531
  </div>
427
532
  );
428
533
  }
429
534
  ```
430
535
 
431
- ### 🔄 ストリーミングMarkdown構文処理
432
-
433
- **核心問題**:ストリーミング出力時に不完全なMarkdown構文がレンダリングエラーを引き起こす
434
-
435
- ```tsx
436
- // 🚨 問題シナリオ
437
- push('#'); // "# "
438
- push(' '); // "# "
439
- push('タイトル'); // "# タイトル"
440
- push('\n'); // "# タイトル\n"
441
- push('1'); // "# タイトル\n1" ← ここで段落として誤解析される
442
- push('.'); // "# タイトル\n1." ← 正しいリストを形成
443
- push(' 項目'); // "# タイトル\n1. 項目"
444
- ```
445
-
446
- **✅ スマート解決策**:内蔵同期バッファリングメカニズム
447
-
448
- ```tsx
449
- // コンポーネントが構文境界をインテリジェントに処理
450
- const handleStreamingMarkdown = () => {
451
- const chunks = ['#', ' ', '使用', 'スキル', '\n', '1', '.', ' ', 'スキル1', '\n', '2', '.', ' スキル2'];
452
-
453
- chunks.forEach((chunk) => {
454
- markdownRef.current?.push(chunk, 'answer');
455
- // 遅延不要、コンポーネントが内部でインテリジェントにバッファリング
456
- });
457
- };
458
-
459
- // 🧠 インテリジェント処理フロー:
460
- // 1. "# 使用スキル\n1" のような不完全な構文をリアルタイム検出
461
- // 2. インテリジェントバッファリング、より多くの文字を待機
462
- // 3. "." を受信して "1." を形成した後すぐに処理
463
- // 4. ゼロ遅延、純粋な同期処理
464
- ```
465
-
466
- **サポートされる構文検出**:
467
-
468
- ````typescript
469
- // ✅ 完全な構文(即座に処理)
470
- '## タイトル'; // 完全なタイトル
471
- '1. リスト項目'; // 完全なリスト項目
472
- '- 項目'; // 完全な順序なしリスト
473
- '> 引用コンテンツ'; // 完全な引用
474
- '```javascript'; // コードブロック開始
475
- '```'; // コードブロック終了
476
- '改行で終わるコンテンツ\n'; // 改行境界
477
- '$a + b$'; // 完全な数式
478
- '$$\\sum x$$'; // 完全なブロック数式
479
-
480
- // 🔄 不完全な構文(インテリジェントバッファリング)
481
- '##'; // タイトル記号のみ
482
- '1'; // 数字のみ
483
- '```java'; // 可能性のあるコードブロック開始
484
- '$a +'; // 不完全な数式
485
- ````
486
-
487
- ---
488
-
489
536
  ## 🔧 ベストプラクティス
490
537
 
491
538
  ### 1. パフォーマンス最適化
@@ -494,40 +541,41 @@ const handleStreamingMarkdown = () => {
494
541
  // ✅ 推奨設定
495
542
  <DsMarkdown
496
543
  timerType="requestAnimationFrame"
497
- interval={15} // 15-30msが最適な体験
544
+ interval={15} // 15-30ms が最適な体験
498
545
  />
499
546
 
500
- // ❌ 小さすぎる間隔を避ける
547
+ // ❌ 過小な間隔は避ける
501
548
  <DsMarkdown interval={1} /> // パフォーマンス問題を引き起こす可能性
502
549
  ```
503
550
 
504
551
  ### 2. ストリーミングデータ処理
505
552
 
506
553
  ```tsx
507
- // ✅ 推奨:命令的API
554
+ // ✅ 推奨:命令的 API
508
555
  const ref = useRef<MarkdownCMDRef>(null);
509
556
  useEffect(() => {
510
557
  ref.current?.push(newChunk, 'answer');
511
558
  }, [newChunk]);
512
559
 
513
- // ❌ 避ける:頻繁なchildren更新
560
+ // ❌ 避ける:頻繁な children 更新
514
561
  const [content, setContent] = useState('');
515
- // 毎回の更新でコンテンツ全体を再解析
562
+ // 各更新で全コンテンツを再解析
516
563
  ```
517
564
 
518
565
  ### 3. 数式最適化
519
566
 
520
567
  ```tsx
521
- // ✅ 推奨:数式スタイルを必要に応じて読み込み
568
+ // ✅ 推奨:オンデマンドで数式スタイルを読み込み
522
569
  import 'ds-markdown/style.css';
523
570
  import 'ds-markdown/katex.css'; // 必要な時のみインポート
524
571
 
525
- // ✅ 推奨:区切り文字の合理的な使用
526
- // シンプルな数式には $...$ で簡潔さを
527
- // 複雑な数式には $$...$$ で明確さを
572
+ // ✅ 推奨:適切な区切り文字の使用
573
+ // シンプルな数式には $...$ がより簡潔
574
+ // 複雑な数式には $$...$$ がより明確
528
575
 
529
- // 避ける:不要な時に数式を有効にする
530
- <DsMarkdown math={{ isOpen: true }}>プレーンテキストコンテンツ</DsMarkdown>;
576
+ // 推奨:プラグイン設定
577
+ import { katexPlugin } from 'ds-markdown/plugins';
578
+ <DsMarkdown plugins={[katexPlugin]}>数式コンテンツ</DsMarkdown>;
531
579
  ```
532
580
 
533
581
  ### 4. 型安全性
@@ -536,7 +584,7 @@ import 'ds-markdown/katex.css'; // 必要な時のみインポート
536
584
  import { MarkdownCMDRef } from 'ds-markdown';
537
585
 
538
586
  const ref = useRef<MarkdownCMDRef>(null);
539
- // 完全なTypeScript型ヒント
587
+ // 完全な TypeScript 型ヒント
540
588
  ```
541
589
 
542
590
  ### 5. スタイルカスタマイズ