feat(gui): add mobile bottom tab navigation (Phase 2-B of #572)#583
Merged
Conversation
MobileGui に 5 つのボトムタブナビゲーションを追加: ブロック / Ruby / スプライト / コスチューム / 音 挙動: - ブロック / Ruby / コスチューム / 音 はクリックすると upstream の editorTab Redux にディスパッチして既存タブを切り替える (上部タブと下部タブが同期して動く) - スプライトタブは mobile 固有の placeholder。クリックで bottom-tabs 内の active 状態だけ切り替わり、upstream の editorTab には影響しない。 実際の全画面スプライト UI は後続 PR で追加する - 表示位置は position: fixed + visualViewport API で viewport 下端に追従 (Phase 1 のバナーと同じ仕組み) - スクロールバーは非表示、タッチ・ホイールでスクロール自体は可能 upstream への影響: - 一切なし。新規ファイル + 既存 Smalruby ファイル (mobile-gui.jsx, locales) のみ修正 実装メモ: - MobileBottomTabs は createPortal で document.body 直下に出すため、 GUI 内側の IntlProvider が見えない。MobileGui で ConnectedIntlProvider を別途包んで FormattedMessage を有効化した - Sprite キーだけ tabIndex: null にしておき、handleClick で data-tab-key 属性から判定 - react/jsx-no-bind 回避のため、各ボタンの onClick は同一の useCallback にまとめ、data-tab-key で識別 検証 (Playwright, viewport 390x844): - ?mobile_gui=1 で 5 タブが viewport 下部に表示 - Ruby タブクリック → bottom-tabs と upstream-tabs 両方が Ruby に切替 - Sprite タブクリック → bottom-tabs では active、upstream は前の選択を維持 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-2b-bottom-tabs/ |
Phase 2-B のボトムタブ (issue #572) と Phase 1 の警告バナーが両方 viewport 下端を占有して重なる問題を解消する。 narrow-screen-warning の visualViewport 位置決め JS で、DOM 上に mobile-bottom-tabs がある場合はその高さ分だけ banner.top を上げる: top = vv.offsetTop + vv.height - bannerHeight - tabsHeight これでバナーがタブの上に積み上がり、両方が同時に視認できる。 タブが存在しない (Phase 1 のみのケース) では tabsHeight=0 なので 従来どおり viewport 下端に貼り付く (リグレッションなし)。 Refs #572 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
28964ae to
62565df
Compare
タブ表示の調整 (issue #572 Phase 2-B フォローアップ): 1. 各タブのアイコンを upstream の SVG に統一 - コード: components/gui/icon--code.svg (puzzle piece) - ルビー: components/gui/icon--ruby.svg (Smalruby diamond) - スプライト: components/action-menu/icon--sprite.svg (cat) - コスチューム: components/gui/icon--costumes.svg (paint brush) - 音: components/gui/icon--sounds.svg (speaker) 2. ラベルを upstream の翻訳キーに統一 - 「ブロック」→「コード」(gui.gui.codeTab) - 「ルビー」(gui.smalruby3.gui.rubyTab) - 「コスチューム」(gui.gui.costumesTab) - 「音」(gui.gui.soundsTab) - スプライトのみ Smalruby 専用キー (gui.mobileBottomTabs.sprite) 3. data-testid を `mobile-bottom-tabs-block` → `mobile-bottom-tabs-code` に変更 4. ?mobile_gui=1 のときは Phase 1 警告バナーを非表示 (mobile UI で既に 最適化されているため案内不要) ロケールから不要になった 4 キー (block/ruby/costume/sound) を削除。 sprite キーのみ残す。 Refs #572 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
issue #572 Phase 2-B フォローアップ: 1. ボトムタブの順序を変更: 旧: コード / ルビー / スプライト / コスチューム / 音 新: スプライト / コード / コスチューム / 音 / ルビー (要望: スプライトを最左に、ルビーを最右に) 2. スプライトアイコンを PC 画面右下のスプライト追加 FAB と同じ見た目に - icon--sprite.svg (action-menu) を 26x26 紫円背景に白アイコンで配置 - 他のタブアイコンよりやや目立つ FAB 風スタイル 3. スプライトタブの翻訳キーを upstream の `gui.SpriteInfo.sprite` に変更 - 元々 sprite-info パネルのラベルとして存在していたキーを再利用 - Smalruby 専用の `gui.mobileBottomTabs.sprite` をロケールから削除 (3 言語 ja / ja-Hira / en) 4. data-testid `mobile-bottom-tabs-block` → `mobile-bottom-tabs-code` に追従 Refs #572 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…rite tab issue #572 Phase 2-B フォローアップ: - 紫の丸い背景と "+" バッジを削除し、ネコ単体のアイコンに変更 - 他のタブアイコンと同じ purple (#855CD6) 単色塗りで統一感 実装: - 新規 Smalruby SVG: components/mobile-bottom-tabs/icon--sprite-cat.svg upstream の icon--sprite.svg からネコ部分のパスのみ抽出、fill を白から紫へ - mobile-bottom-tabs.jsx の `iconKind: 'sprite-fab'` 分岐を削除し、 通常タブと同じ <img className={styles.icon}> でレンダリング - mobile-bottom-tabs.css の sprite-fab-icon / sprite-fab-img クラスを削除 Refs #572 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
18c3813 to
7745eee
Compare
github-actions Bot
pushed a commit
that referenced
this pull request
Apr 29, 2026
…-phase-2b-bottom-tabs feat(gui): add mobile bottom tab navigation (Phase 2-B of #572)
This was referenced Apr 29, 2026
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
MobileGuiに 5 つのボトムタブナビゲーションを追加 (issue #572 Phase 2-B)。タブ:
?mobile_gui=1URL フラグ + 狭幅 viewport (< 768px) のときのみ表示されるオプトイン機能。挙動
editorTabRedux にディスパッチ (activateTab(BLOCKS_TAB_INDEX))。上部タブも同期するRUBY_TAB_INDEXbottom-tabs内 active 状態のみ切替。upstream のeditorTabは変更しない (実際の全画面スプライト UI は後続 PR で追加)editorTabにディスパッチ、COSTUMES_TAB_INDEXSOUNDS_TAB_INDEX設計
position: fixed+visualViewportAPI で viewport 下端に追従 (Phase 1 のバナーと同じ仕組み)scrollbar-width: none/::-webkit-scrollbar { display: none }で隠すdocument.body直下にレンダリングし、<GUI>の祖先要素 (transform 等) の影響を受けない<GUI>のIntlProvidercontext が届かないため、MobileGui でConnectedIntlProviderを個別に包んでFormattedMessageを有効化変更ファイル
新規 (Smalruby 固有)
src/components/mobile-bottom-tabs/{mobile-bottom-tabs.jsx,css,index.js}— タブ本体test/unit/components/mobile-bottom-tabs.test.jsx— 8 ユニットテスト (タブ存在 / active 切替 / dispatch / sprite ローカル状態)変更
src/components/mobile-gui/mobile-gui.jsx—<MobileBottomTabs>を<ConnectedIntlProvider>で包んで追加src/locales/{ja,ja-Hira,en}.js— 5 タブのラベル翻訳追加.prettierignore/smalruby-prettier-files.md— 新規ファイルをホワイトリストに追加upstream への影響
ゼロ。upstream のファイルには触れていない (Phase 2-A の
render-gui.jsx改修のみがこれまで唯一の upstream 変更)。検証
ユニットテスト (jest, 8 件)
editorTab由来の active 状態が反映されるactivateTabが正しい引数で呼ばれるactivateTabが呼ばれず、ローカル active 状態だけ立つPlaywright (Chromium, viewport 390×844)
?no_beforeunload=1&mobile_gui=1で 5 タブが viewport 下端に表示data-active=true+ upstreamaria-selected=true両方が Ruby に切替Phase 2 進捗
Test plan
Related
notes/issue-572-responsive-ux-design.md🤖 Generated with Claude Code