Skip to content

Put Cancel and Commit in a bar at the top of the commit sheet - #19

Merged
simonhamp merged 2 commits into
NativePHP:mainfrom
KaitoMuraoka:feature/commit-sheet-toolbar
Oct 20, 2026
Merged

simonhamp merged 2 commits into
NativePHP:mainfrom
KaitoMuraoka:feature/commit-sheet-toolbar

Conversation

@KaitoMuraoka

Copy link
Copy Markdown
Contributor

Summary

The new commit and quote sheets now have Cancel, the title and Commit in a bar along the top, the way compose sheets look on each platform. native-ui's bottom sheet has no toolbar, so the bar is a row pinned outside the scroll view, and it stays put while the field scrolls.

  • iOS: Cancel is a Liquid Glass button, and Commit a prominent one in your colour (ios:glass, ios:glass:prominent), following the HIG's sheet toolbars.
  • Android: both are text buttons, as in Material 3's full-screen dialog header. Android's sheet already has M3's drag handle above its content, so only iOS gets room above the bar.
  • The two buttons have the same minimum width and the same padding either side, so the title sits in the middle. The buttons and the 56pt bar grow with larger text sizes rather than clipping.
  • Cancel closes the sheet as a swipe does. The draft stays stashed and comes back marked stash@{0}, and an a11y-hint tells VoiceOver and TalkBack so.
  • Why devnull didn't take a commit now shows above the field, near Commit, rather than under the quoted card where the keyboard can hide it.
  • Commit::fits() holds the length check, which the Commit button and commitFromSheet() both use.

Testing

  • php artisan test --compact --filter='ComposeSheet|Quote|DraftStash|Saved': 67 passed
  • New tests: Cancel keeps the draft through close → dismiss → reopen, and the bar is glass on iOS and text buttons on Android.
  • Android emulator (Pixel 9a): typed and tapped Cancel at once, three times. The last characters were stashed every time. I didn't test the same race on Commit, since the emulator is signed in to a real account.

Not covered

  • Android only flushes a debounced field on blur, while iOS flushes before a press. Typing and tapping Commit at once could in theory send a body short its last characters. It didn't happen with Cancel.
  • Native UI has no sheet toolbar element. Moving to SwiftUI's .toolbar and M3's TopAppBar would need a plugin or a change to native-ui upstream.

ScreenShot

Before After
iOS Before-ios After-ios
Android Before-android After-android

References

Explanation in Japanese

概要

新しいコミットシートと引用シートでは、キャンセル・タイトル・コミットが上部のバーに並ぶようになりました。各プラットフォームの作成(compose)シートと同じ見た目です。native-ui のボトムシートにはツールバーがありません。そのため、このバーはスクロールビューの外に固定した行として実装しており、入力欄をスクロールしても動きません。

  • iOS: HIG のシートツールバーに従い、キャンセルは Liquid Glass ボタン、コミットはユーザーのカラーを使った prominent ボタンです(ios:glass、ios:glass:prominent)。
  • Android: Material 3 のフルスクリーンダイアログのヘッダーと同じく、どちらもテキストボタンです。Android のシートにはコンテンツの上に M3 のドラッグハンドルが最初からあるため、バーの上に余白を設けるのは iOS だけです。
  • 2 つのボタンは最小幅も左右のパディングも同じなので、タイトルは中央に来ます。ボタンと 56pt のバーは、文字サイズを大きくすると切れずに広がります。
  • キャンセルはスワイプと同じようにシートを閉じます。下書きは stash されたまま残り、次に開いたときに stash@{0} の印付きで戻ってきます。このことは a11y-hint で VoiceOver と TalkBack に伝えます。
  • devnull がコミットを受け付けなかった理由は、入力欄の上(コミットボタンの近く)に表示するようにしました。以前は引用カードの下に出ていて、キーボードで隠れることがありました。
  • 長さのチェックは Commit::fits() にまとめ、コミットボタンと commitFromSheet() の両方から使っています。

テスト

  • php artisan test --compact --filter='ComposeSheet|Quote|DraftStash|Saved': 67 件成功
  • 追加したテスト: キャンセルしても 閉じる → dismiss → 再表示 の流れで下書きが残ること。バーが iOS ではガラス、Android ではテキストボタンになること。
  • Android エミュレーター(Pixel 9a): 入力しながら同時にキャンセルをタップする操作を 3 回試しました。3 回とも最後の文字まで stash されました。コミットでの同じ競合はテストしていません。エミュレーターが実際のアカウントでサインインしているためです。

対象外

  • Android では、debounce された入力欄の内容が確定(flush)されるのはフォーカスが外れたときだけです。iOS ではボタンを押す前に確定されます。そのため理論上は、入力しながら同時にコミットをタップすると、最後の数文字が欠けた本文が送信される可能性があります。キャンセルでは起きませんでした。
  • Native UI にはシートのツールバー要素がありません。SwiftUI の .toolbar や M3 の TopAppBar に移行するには、プラグインを作るか、native-ui の upstream を変更する必要があります。

参考資料

@KaitoMuraoka
KaitoMuraoka marked this pull request as ready for review October 19, 2026 17:17
@KaitoMuraoka KaitoMuraoka changed the title put Cancel and Commit in a bar at the top of the commit sheet Put Cancel and Commit in a bar at the top of the commit sheet Oct 19, 2026
@simonhamp

Copy link
Copy Markdown
Member

can you fix the conflicts?

The new commit and quote sheets have Cancel, the title and Commit in a bar along the top, pinned outside the scroll view so it stays while the field scrolls. native-ui's bottom sheet has no toolbar, so the bar is a row. On iOS, Cancel is a Liquid Glass button and Commit a prominent one in your colour, as the HIG's sheet toolbars float over content. On Android they're text buttons, as in Material 3's full-screen dialog header.

The two buttons are the same width with the same padding either side, so the title sits in the middle, and both they and the 56pt bar grow with larger text rather than clipping. Android's sheet already has Material 3's drag handle above its content, so only iOS gets room above the bar.

Cancel closes the sheet as a swipe does, and the draft stays stashed. Why devnull didn't take a commit now shows above the field, near Commit, rather than under the quoted card where the keyboard can hide it.
@KaitoMuraoka

Copy link
Copy Markdown
Contributor Author

Yes! I'm working on that right now.

@KaitoMuraoka
KaitoMuraoka force-pushed the feature/commit-sheet-toolbar branch from 0a14f74 to 1d90aaa Compare October 20, 2026 11:51
Cancel tells VoiceOver and TalkBack that it keeps the draft for next time, since its name suggests otherwise. hideCommitSheet's docblock now says Cancel uses it too and that it mustn't forget the draft.

Whether a body is long enough to commit is Commit::fits(), which the sheet's Commit button and commitFromSheet() both ask, so the button can't be enabled for a body the sheet won't send.
@KaitoMuraoka
KaitoMuraoka force-pushed the feature/commit-sheet-toolbar branch from 1d90aaa to 8b2bdab Compare October 20, 2026 11:52
@simonhamp
simonhamp merged commit 8bc157b into NativePHP:main Oct 20, 2026
1 check passed
@KaitoMuraoka

Copy link
Copy Markdown
Contributor Author

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants