feat(gui): add MobileTopBar with run-fullscreen button (Phase 2-C of #572)#584
Merged
Merged
Conversation
issue #572 Phase 2-C: ステージ全画面プレビュー機能の最小実装。 実装: - 新規 MobileTopBar コンポーネント - 上部バーに緑の旗 (▶) ボタンのみ配置 (ハンバーガー等は PR-2E で追加) - クリックで upstream の setFullScreen(true) + vm.start() + vm.greenFlag() を一括ディスパッチ → 自動的にステージプレビュー + 実行開始 - position: fixed + visualViewport API で viewport 上端に追従 - isFullScreen=true のときは隠す (ステージプレビュー専念のため) - MobileBottomTabs も isFullScreen=true で隠すよう更新 - MobileGui の構成: <GUI/> + <MobileTopBar/> + <MobileBottomTabs/> 全画面からの戻り方は upstream の StageHeader が提供する縮小ボタンで OK (PR-2C ではこれを利用)。将来的に PR-2C+ で左上 ✕ ボタンに置き換える等の polish を入れる余地はある。 検証 (Playwright, viewport 390x844): - mobile_gui=1 で ▶ ボタンが上部バーに表示 - ▶ クリック → 全画面ステージ + 緑旗実行 + 上下バー非表示 - 縮小ボタン → 全画面解除 + 上下バー再表示 - ユニットテスト 12/12 (mobile-top-bar 4 件 + mobile-bottom-tabs 8 件) Refs #572 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
🚀 Preview deployed: https://smalruby.jp/smalruby3-editor/fix/issue-572-phase-2c-stage-fullscreen/ |
issue #572 Phase 2-C のフィードバック対応: 1. ▶ アイコンを緑旗から play triangle (▶) に変更 - 緑旗ブロック実行とは異なる動作 (全画面起動 + 自動実行) のため、 アイコンを区別する - 新規 Smalruby SVG: components/mobile-top-bar/icon--play.svg 2. 全画面中も上部バーを表示し続けるよう変更 - 旧: isFullScreen=true で MobileTopBar を null - 新: 常に表示。アイコンを ▶ → ⏹ に切替、クリックで vm.stopAll() + setFullScreen(false) で停止 + 戻る - 新規 Smalruby SVG: components/mobile-top-bar/icon--stop.svg 3. 全画面解除後にボトムタブが viewport 上端に移動するバグを修正 - usePositionAtVisualViewportBottom / Top の useLayoutEffect 依存配列に enabled を追加し、isFullScreen フラグの変化で再計算 - 旧: 一度だけ走り、コンポーネント再表示時に位置が再計算されない - 新: enabled=true→false→true の遷移で update() が再走 検証 (Playwright, viewport 390x844): - 編集中: ▶ アイコン表示 - ▶ クリック → 全画面 + 自動実行、上部バーは ⏹ 表示で残る - ⏹ クリック → 停止 + 全画面解除、上下バーが正しい位置に戻る - ユニットテスト 13/13 (mobile-top-bar 5 件、mobile-bottom-tabs 8 件) 未対応 (フォローアップ): - 全画面ステージの左右白い余白 = upstream の stage-wrapper.full-screen が 4:3 アスペクト比で width-based、iPhone 縦持ちで下に余白が出る (CSS 上書きが必要、別 PR で polish) Refs #572 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2511bc1 to
c0fda1c
Compare
issue #572 Phase 2-C のフィードバック対応: 1. 全画面ステージの upstream UI が MobileTopBar に隠れる問題を修正 - MobileTopBar の高さを CSS 変数 --smalruby-mobile-top-bar-height に 反映 (visualViewport の update タイミングで JS が documentElement に setProperty) - mobile-top-bar.css に :global ブロックを追加し、upstream の stage-header overlay (top: 0) と stage-wrapper.full-screen (top: 2.75rem) をその変数分だけ下にシフト - これにより fullscreen 中も緑旗・停止・縮小ボタンが MobileTopBar の 直下に表示される 2. ▶/⏹ ボタンクリック後にフォーカスを外す - upstream の <GreenFlag> と同じ挙動 (target.blur()) - ステージにキーボードイベントを渡せるようにする (キー入力で動く プログラムが mobile プレビューでも動作する) 検証 (Playwright, viewport 390x844): - ▶ クリック → 全画面起動。MobileTopBar (⏹) の下に upstream 緑旗/停止/ 縮小ボタンが表示される - ⏹ クリック → 全画面解除、上下バーが元位置に復帰 - ユニットテスト 5/5 (mobile-top-bar) Refs #572 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
issue #572 Phase 2-C: 全画面ステージの左右見切れを修正。 原因: - upstream の getStageDimensions(isFullScreen=true) は width = window.innerWidth (= 390 on iPhone) で計算する - stage に設定されている `border: 3px solid` は box-sizing: content-box のため width に加算され、結果 stage box の実幅は 390 + 6 = 396px となり viewport を 3px ずつ左右にはみ出す (画面外) 修正: - mobile-top-bar.css の :global ブロックで `[class*="stage_full-screen"]` に box-sizing: border-box を上書き - これで border が box 幅に含まれ、stage box は viewport 幅と一致する - 内部の canvas は別の sizing 経路で制御されるため影響なし 検証 (Playwright, viewport 390x844): - 旧: stageDivRect.width = 396 (-3 ~ 393) - 新: stageDivRect.width = 390 (0 ~ 390) ✓ Refs #572 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
github-actions Bot
pushed a commit
that referenced
this pull request
Apr 29, 2026
…-phase-2c-stage-fullscreen feat(gui): add MobileTopBar with run-fullscreen button (Phase 2-C of #572)
10 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
issue #572 Phase 2-C: モバイル用ステージ全画面プレビュー機能の最小実装。
実装
新規コンポーネント:
MobileTopBarsetFullScreen(true)(upstream の mode reducer)vm.start()(未起動時のみ)vm.greenFlag()— 自動実行開始position: fixed+visualViewportAPI で viewport 上端に追従 (Phase 1 のバナー、Phase 2-B のボトムタブと同じ仕組み)isFullScreen=trueのときは自身を非表示 (ステージプレビューに専念)MobileBottomTabs の更新
isFullScreen=trueのときは非表示にする条件分岐を追加state.scratchGui.mode.isFullScreenを購読MobileGui の構成
全画面からの戻り方
upstream の
StageHeaderが提供する縮小ボタン (画面右上) で全画面解除 → MobileTopBar / MobileBottomTabs が再表示される。将来的なポリッシュ (PR-2C 後続 or 別 PR):
これらは upstream の StageHeader / Stage の CSS 上書きが必要なので別 PR で実装する想定。
変更ファイル
新規 (Smalruby 固有)
src/components/mobile-top-bar/{mobile-top-bar.jsx,css,index.js}— Top bar 本体test/unit/components/mobile-top-bar.test.jsx— 4 ユニットテスト (描画 / fullscreen 時非表示 / vm.start 呼出 / isStarted=true で start スキップ)変更
src/components/mobile-bottom-tabs/mobile-bottom-tabs.jsx—isFullScreenprop で非表示化src/components/mobile-gui/mobile-gui.jsx—<MobileTopBar />を追加test/unit/components/mobile-bottom-tabs.test.jsx— 既存テストにisFullScreen={false}prop 追加メタファイル
.prettierignore/smalruby-prettier-files.md— 新規ファイルをホワイトリストに追加検証
ユニットテスト (jest, 12 件)
Playwright (Chromium, viewport 390×844)
?mobile_gui=1で初期表示Phase 2 進捗
Test plan
🤖 Generated with Claude Code