Goal
iPadOS で Ruby タブを開くと、Monaco 組み込みの IPadShowKeyboard ウィジェット(textarea.iPadShowKeyboard、58×36px)がエディタ右下角(BOTTOM_RIGHT_CORNER)に表示され、Smalruby 独自の zoom コントロール(特に最下段の zoom リセットボタン)と重なって操作できない。
このウィジェットを CSS で無条件に非表示にし、代替としてソフトウェアキーボードの表示/非表示を切り替えるボタンを Ruby ツールバーに追加する(タッチデバイスのみ表示)。
原因調査の結果
monaco-editor@0.55.1 の IPadShowKeyboard contribution(editor.main.js で無条件登録)が原因
isIOS 判定(UA に Macintosh/iPad/iPhone を含む かつ maxTouchPoints > 0 — iPadOS Safari は UA が "Macintosh" なので該当)のときのみ overlay widget を右下角に追加する
- ウィジェットの機能はタップ時の
editor.focus()(iOS でソフトウェアキーボードを出すレガシーなフォールバック)
- Smalruby の zoom コントロール(
ruby-tab.css の .zoomControlsWrapper、bottom: 31px; right: 31px)と位置が重なる
- Monaco standalone API には built-in contribution を除外する公開オプションがないため、CSS で非表示にする
機能設計(キーボードトグルボタン)
- 表示:
editorRef.focus() — ボタンタップ(user gesture)内で Monaco の hidden textarea にフォーカス → iOS/Android でソフトウェアキーボードが出る(Monaco ウィジェットと同じ仕組み)
- 非表示: エディタの textarea (
.inputarea) を blur() → キーボードが閉じる
- 状態表示:
onDidFocusEditorText / onDidBlurEditorText を購読して aria-pressed とアクティブスタイルを切り替え(auto-correct ボタンと同じパターン)
- 表示条件:
navigator.maxTouchPoints > 0(タッチデバイス全般 = iPad + Android。Android でも「キーボードを閉じる」用途で有用)。デスクトップでは非表示
- 配置: Edit Part(undo/redo/search の隣)、
data-testid="ruby-toolbar-keyboard"
Affected Files
packages/scratch-gui/src/containers/ruby-tab/ruby-tab.css — .iPadShowKeyboard を display: none に(既存の find-widget override と同じパターン)
packages/scratch-gui/src/components/ruby-toolbar/ruby-toolbar.jsx — キーボードトグルボタン追加(editorRef の focus/blur 購読、タッチ判定)
packages/scratch-gui/src/components/ruby-toolbar/messages.js — keyboardShow / keyboardHide メッセージ
packages/scratch-gui/src/components/ruby-toolbar/icon--keyboard.svg — 新規アイコン
packages/scratch-gui/src/lib/screen-utils.js — isTouchDevice() ヘルパー追加(既存ファイル)
packages/scratch-gui/src/locales/ja.js / ja-Hira.js — 日本語訳
packages/scratch-gui/test/unit/components/ruby-toolbar-keyboard.test.jsx — 新規ユニットテスト(prettier whitelist 2 箇所更新が必要)
packages/scratch-gui/test/integration/ruby-tab/ — 回帰テスト
.claude/rules/scratch-gui/e2e-test.md — ruby-toolbar-keyboard testid を一覧に追加
docs/(ruby-tab / mobile-ui 該当ドキュメント)— UI 変更の記載 + スクリーンショット
Implementation Steps
Phase 1: Monaco キーボードウィジェットの CSS 非表示
Phase 2: キーボードトグルボタン(TDD)
Phase Final: Integration テスト + ドキュメント
Definition of Done
Test Plan
| Type |
Timing |
Target |
| Unit (TDD) |
実装前 RED→GREEN |
isTouchDevice 判定、ボタン表示条件、focus/blur、aria-pressed |
| Integration |
実装後 |
.iPadShowKeyboard の display:none 回帰テスト |
| Browser (Playwright) |
CI green 後 |
iPad UA エミュレーションで DoD 確認 |
| 実機 iPad |
最後 |
キーボード出現/消失の手動確認 |
Risks & Open Questions
- blur は Monaco の textarea (
.inputarea) への DOM 操作になる(Monaco API に公開の blur メソッドがないため)。read-only な操作のためリスクは低い(設計承認済み)
関連
Feedback: smalruby/smalruby3-develop#87
Goal
iPadOS で Ruby タブを開くと、Monaco 組み込みの
IPadShowKeyboardウィジェット(textarea.iPadShowKeyboard、58×36px)がエディタ右下角(BOTTOM_RIGHT_CORNER)に表示され、Smalruby 独自の zoom コントロール(特に最下段の zoom リセットボタン)と重なって操作できない。このウィジェットを CSS で無条件に非表示にし、代替としてソフトウェアキーボードの表示/非表示を切り替えるボタンを Ruby ツールバーに追加する(タッチデバイスのみ表示)。
原因調査の結果
monaco-editor@0.55.1のIPadShowKeyboardcontribution(editor.main.jsで無条件登録)が原因isIOS判定(UA にMacintosh/iPad/iPhoneを含む かつmaxTouchPoints > 0— iPadOS Safari は UA が "Macintosh" なので該当)のときのみ overlay widget を右下角に追加するeditor.focus()(iOS でソフトウェアキーボードを出すレガシーなフォールバック)ruby-tab.cssの.zoomControlsWrapper、bottom: 31px; right: 31px)と位置が重なる機能設計(キーボードトグルボタン)
editorRef.focus()— ボタンタップ(user gesture)内で Monaco の hidden textarea にフォーカス → iOS/Android でソフトウェアキーボードが出る(Monaco ウィジェットと同じ仕組み).inputarea) をblur()→ キーボードが閉じるonDidFocusEditorText/onDidBlurEditorTextを購読してaria-pressedとアクティブスタイルを切り替え(auto-correct ボタンと同じパターン)navigator.maxTouchPoints > 0(タッチデバイス全般 = iPad + Android。Android でも「キーボードを閉じる」用途で有用)。デスクトップでは非表示data-testid="ruby-toolbar-keyboard"Affected Files
packages/scratch-gui/src/containers/ruby-tab/ruby-tab.css—.iPadShowKeyboardをdisplay: noneに(既存の find-widget override と同じパターン)packages/scratch-gui/src/components/ruby-toolbar/ruby-toolbar.jsx— キーボードトグルボタン追加(editorRef の focus/blur 購読、タッチ判定)packages/scratch-gui/src/components/ruby-toolbar/messages.js—keyboardShow/keyboardHideメッセージpackages/scratch-gui/src/components/ruby-toolbar/icon--keyboard.svg— 新規アイコンpackages/scratch-gui/src/lib/screen-utils.js—isTouchDevice()ヘルパー追加(既存ファイル)packages/scratch-gui/src/locales/ja.js/ja-Hira.js— 日本語訳packages/scratch-gui/test/unit/components/ruby-toolbar-keyboard.test.jsx— 新規ユニットテスト(prettier whitelist 2 箇所更新が必要)packages/scratch-gui/test/integration/ruby-tab/— 回帰テスト.claude/rules/scratch-gui/e2e-test.md—ruby-toolbar-keyboardtestid を一覧に追加docs/(ruby-tab / mobile-ui 該当ドキュメント)— UI 変更の記載 + スクリーンショットImplementation Steps
Phase 1: Monaco キーボードウィジェットの CSS 非表示
.monaco-editor内に.iPadShowKeyboard要素を注入し computed style がdisplay: noneであることを assertruby-tab.cssにルール追加fix: hide Monaco iPad keyboard widget overlapping zoom controlsPhase 2: キーボードトグルボタン(TDD)
isTouchDevice()の判定ロジック(maxTouchPoints のモック)editorRef.focus()が呼ばれる(非フォーカス時)/textarea の blur が呼ばれる(フォーカス時)aria-pressedが切り替わるisTouchDevice()+ ボタン実装 + アイコン + messages + localesfeat: add software keyboard toggle button to Ruby toolbarPhase Final: Integration テスト + ドキュメント
Definition of Done
.iPadShowKeyboardがdisplay: none)ruby-toolbar-keyboardボタンが表示されるdocument.activeElementが Monaco の textarea)Test Plan
.iPadShowKeyboardの display:none 回帰テストRisks & Open Questions
.inputarea) への DOM 操作になる(Monaco API に公開の blur メソッドがないため)。read-only な操作のためリスクは低い(設計承認済み)関連
Feedback: smalruby/smalruby3-develop#87