Skip to content

dialog: Support configurable entrance animations - #3405

Merged
huacnlee merged 3 commits into
longbridge:mainfrom
xxww0098:dialog-pop-in-entrance
Oct 8, 2026
Merged

huacnlee merged 3 commits into
longbridge:mainfrom
xxww0098:dialog-pop-in-entrance

Conversation

@xxww0098

@xxww0098 xxww0098 commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Description

Dialogs always slide from the window top to their resting position while fading in. When a dialog rests low in a tall window, it crosses much of the window before settling.

Add a shared DialogEntrance API so applications can choose the entrance for both Dialog and AlertDialog:

dialog.entrance(DialogEntrance::FadeSlide)
alert.entrance(DialogEntrance::Fade)
Entrance Behavior
SlideDown (default) Existing slide from the window top with its original timing and easing.
Fade Fade in at the final position without movement.
FadeSlide Fade in with short downward travel from above the resolved resting position.
None Display the surface and backdrop immediately.

Fade and FadeSlide use the theme's normal duration and enter easing. FadeSlide uses the theme's short motion distance and applies travel after window-boundary positioning, so a dialog clamped upwards still moves relative to its actual resting position. Travel is shortened when there is insufficient space above the surface, and pointer hit testing follows the moving surface.

Reduced motion immediately displays the final state for every option. A zero theme duration also skips the fade entrances. Surface opacity, shadows, and the backdrop use the same entrance timing. Closing remains immediate.

The Dialog story exposes all four choices under Options → Entrance. Dialog and AlertDialog documentation is updated in English and Chinese.

Public API

gpui-component

  • #[non_exhaustive] pub enum dialog::DialogEntrance { SlideDown, Fade, FadeSlide, None } — Select the shared entrance presentation. Implements Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, and Deserialize.
  • DialogEntrance::SlideDown — Default; preserve the existing slide and fade entrance.
  • DialogEntrance::Fade — Fade at the final position without movement.
  • DialogEntrance::FadeSlide — Fade with bounded, theme-defined downward travel.
  • DialogEntrance::None — Immediately show the surface and backdrop.
  • Dialog::entrance(self, entrance: DialogEntrance) -> Self — Choose the dialog entrance.
  • AlertDialog::entrance(self, entrance: DialogEntrance) -> Self — Apply the same entrance policy to an alert dialog.

Breaking Changes

None for existing consumers. The API is additive and SlideDown preserves the existing default behavior.

Validation

  • cargo test -p gpui-component --lib dialog -- --nocapture — 17 passed, covering resolved-boundary travel, intermediate positions, top-edge limits, pointer hit testing, builder defaults, AlertDialog forwarding, reduced motion, immediate keyboard dismissal, and zero theme duration.
  • cargo check -p gpui-component-story — passed.
  • cargo clippy -p gpui-component -p gpui-component-story --all-targets -- --deny warnings — passed.
  • cargo fmt --all --check and git diff --check — passed.

Implementation, tests, and documentation were generated with AI assistance. The story was compile-checked; its animations were not manually compared across platforms.

@huacnlee huacnlee changed the title dialog: Add an opt-in pop-in entrance dialog: Add configurable entrance animations Oct 8, 2026
@huacnlee huacnlee changed the title dialog: Add configurable entrance animations dialog: Support configurable entrance animations Oct 8, 2026
@huacnlee
huacnlee enabled auto-merge (squash) October 8, 2026 06:10
@huacnlee
huacnlee merged commit 6baad8b into longbridge:main Oct 8, 2026
16 checks passed
linruohan pushed a commit to linruohan/gpui-component that referenced this pull request Oct 9, 2026
## Description

Dialogs always slide from the window top to their resting position while
fading in. When a dialog rests low in a tall window, it crosses much of
the window before settling.

Add a shared `DialogEntrance` API so applications can choose the
entrance for both `Dialog` and `AlertDialog`:

```rust
dialog.entrance(DialogEntrance::FadeSlide)
alert.entrance(DialogEntrance::Fade)
```

| Entrance | Behavior |
| --- | --- |
| `SlideDown` (default) | Existing slide from the window top with its
original timing and easing. |
| `Fade` | Fade in at the final position without movement. |
| `FadeSlide` | Fade in with short downward travel from above the
resolved resting position. |
| `None` | Display the surface and backdrop immediately. |

`Fade` and `FadeSlide` use the theme's normal duration and enter easing.
`FadeSlide` uses the theme's short motion distance and applies travel
after window-boundary positioning, so a dialog clamped upwards still
moves relative to its actual resting position. Travel is shortened when
there is insufficient space above the surface, and pointer hit testing
follows the moving surface.

Reduced motion immediately displays the final state for every option. A
zero theme duration also skips the fade entrances. Surface opacity,
shadows, and the backdrop use the same entrance timing. Closing remains
immediate.

The Dialog story exposes all four choices under Options → Entrance.
Dialog and AlertDialog documentation is updated in English and Chinese.

## Public API

### gpui-component

- `#[non_exhaustive] pub enum dialog::DialogEntrance { SlideDown, Fade,
FadeSlide, None }` — Select the shared entrance presentation. Implements
`Clone`, `Copy`, `Debug`, `Default`, `PartialEq`, `Eq`, `Serialize`, and
`Deserialize`.
- `DialogEntrance::SlideDown` — Default; preserve the existing slide and
fade entrance.
- `DialogEntrance::Fade` — Fade at the final position without movement.
- `DialogEntrance::FadeSlide` — Fade with bounded, theme-defined
downward travel.
- `DialogEntrance::None` — Immediately show the surface and backdrop.
- `Dialog::entrance(self, entrance: DialogEntrance) -> Self` — Choose
the dialog entrance.
- `AlertDialog::entrance(self, entrance: DialogEntrance) -> Self` —
Apply the same entrance policy to an alert dialog.

## Breaking Changes

None for existing consumers. The API is additive and `SlideDown`
preserves the existing default behavior.

## Validation

- `cargo test -p gpui-component --lib dialog -- --nocapture` — 17
passed, covering resolved-boundary travel, intermediate positions,
top-edge limits, pointer hit testing, builder defaults, AlertDialog
forwarding, reduced motion, immediate keyboard dismissal, and zero theme
duration.
- `cargo check -p gpui-component-story` — passed.
- `cargo clippy -p gpui-component -p gpui-component-story --all-targets
-- --deny warnings` — passed.
- `cargo fmt --all --check` and `git diff --check` — passed.

Implementation, tests, and documentation were generated with AI
assistance. The story was compile-checked; its animations were not
manually compared across platforms.

---------

Co-authored-by: xxww0098 <shefkie1957@gmail.com>
Co-authored-by: Jason Lee <huacnlee@gmail.com>
@huacnlee huacnlee mentioned this pull request Oct 12, 2026
huacnlee added a commit that referenced this pull request Oct 12, 2026
## Description

Prepare v0.7.2 on `stable` from the PRs merged into `main` since v0.7.1,
leaving out every change that breaks existing consumers. `stable`
already carries #3371 and #3373; this adds the remaining compatible PRs
with `git cherry-pick -x` and bumps the workspace to 0.7.2.

### Included

- kit: Add optional gpui-fast backend (#3375)
- tooltip: Make show delay and grace period configurable with
`TooltipDefaults` (#3376)
- docs: Explain recovering focus when the focused element stops
rendering (#3386)
- diff: Add readonly patch viewer (#3378)
- kit: Use one Windows manifest with GPUI Fast (#3380)
- test: Make Progress and TitleBar findable in UI tests (#3383)
- input: Preserve selection, focus ring and context menu actions (#3382)
- diff: Add a Git history example and complete review APIs (#3388)
- text_view: Ignore gestures that stay inside one block plugin (#3390)
- text_view: Round the first and last table rows to the frame radius
(#3309)
- menu: Open a context menu with a long press on touch (#3393)
- text_view: Keep narrow table columns on one line (#3399)
- settings: Keep focus rings inside the list viewport (#3394)
- scrollable_mask: Keep rounded scroll-table corners clean at any scroll
offset (#3400)
- dialog: Add margin_top to AlertDialog (#3404)
- input: Add InputState::add_selection for programmatic multi-cursor
(#3403)
- text_selection: Stop writing selection state on every frame (#3407)
- table: Make the sort icon a labelled button (#3396)
- table: Report visible row ranges of one row or none (#3397)
- dialog: Support configurable entrance animations (#3405)
- docs: Explain the open_dialog builder and footer contracts (#3406)
- dock: Hand the focus to the tab that replaces a closed one (#3409)
- dropdown_button: Add A11y names for the menu trigger (#3410)
- text, resizable: Stop notifying state that did not change (#3418)
- editor: Add on-demand completion commands (#3411)
- table: Clear a right-clicked cell's outline on the next click (#3413)
- tab: Scroll a clicked tab into view with the next one peeking (#3419)
- table: Allow a header row height separate from the body (#3420)
- menu: Focus a context menu before its first frame (#3422)
- text: Preserve logical selection across presentation changes (#3421)
- text: Keep inline HTML mark highlights in Markdown (#3425)
- input: Anchor completion/code-action popups to the current frame's
caret (#3412)
- input: Run custom context menu builders after releasing the input
(#3433)
- input: Keep auto-grow rows fitted when the limits change (#3430)
- text: Paint TextView selection under the glyphs (#3439)

Already on `stable`: #3371, #3373.

### Excluded (Breaking Changes)

- #3432 motion: `Easing::sample` now returns values outside `[0, 1]` for
overshooting curves.
- #3415 tab: new `TabVariant::Folder` breaks exhaustive matches.
- #3402 kit: pointer helpers now keep held modifiers; nested
context-menu behavior changes in tests.
- #3384 test: `TestWindowExt` gains required methods.
- #3302 resizable: `ResizeHandle::on_drag` takes `&T` instead of
`Rc<T>`.
- #3389, #3395, #3398 webview: wrapper API changes, `gpui-wry` →
`gpui-webview` rename, and the GPUI Fast requirement.

#3411, #3405 and #3396 have a Breaking Changes section that reads "None"
and are included. #3376 only deprecates `TooltipRequest::placement`, and
#3397 / #3382 change behavior compatibly, so they are included too.

### Adaptations

- `crates/kit/tests/collections.rs` and `crates/kit/tests/rendering.rs`:
conflict resolutions drop the tests that belong to #3402 and keep each
backported PR's own test.
- `test: Keep backported tests on the v0.7.1 test API`: the menu and
completion tests from #3422 and #3412 used `find_all` and
`pointer_down`/`pointer_up` from #3384/#3402. They now query
`gpui_kit::base::test_support::snapshots` and dispatch mouse events
directly.
- `kit: Prepare v0.7.2`: workspace version bump; `Cargo.lock` only
updates workspace members.

## Public API

No new public API beyond what the included PRs add; each lists its items
in its own `## Public API` section (notably #3375, #3376, #3378, #3388,
#3403, #3404, #3405, #3411, #3420).

## How to Test

- `cargo clippy --workspace --all-targets -- --deny warnings` passes on
Linux.
- `cargo test -p gpui-kit --features "test-support component assets"
--test collections --test menu --test input` passes on Linux.
- The macOS-only `rendering` test (#3439 adds one case, the count is
updated to 11) was not run.

AI-assisted: the backport, conflict resolution and test adaptations were
done with Claude Code.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Floyd Wang <codelife721@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Gustave <gustavel@gmail.com>
Co-authored-by: luren <84951845+lurenjia534@users.noreply.github.com>
Co-authored-by: Ylin <ylinwind@gmail.com>
Co-authored-by: ihavecoke <mixboip@gmail.com>
Co-authored-by: Lorenzo <150276837+Bombatomica64@users.noreply.github.com>
Co-authored-by: MR. XIE <113512030+xxww0098@users.noreply.github.com>
Co-authored-by: xxww0098 <shefkie1957@gmail.com>
Co-authored-by: Sola 🌙🤖 <266175376+sola-ryu@users.noreply.github.com>
Co-authored-by: Sola <sola-ryu@users.noreply.github.com>
Co-authored-by: Andy Hsu <i@nn.ci>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Floyd Wang <gassnake999@gmail.com>
Co-authored-by: Daiki Tomioka <20753105+TomiXRM@users.noreply.github.com>
Co-authored-by: Henrik Øgård <henrik@ogard.no>
Co-authored-by: Henrik Øgård <henrikogaard@users.noreply.github.com>
Co-authored-by: Endless <endless@longbridge.com>
Co-authored-by: John Costa <costajohnt@gmail.com>
Co-authored-by: Alexander <87220898+sneffets@users.noreply.github.com>
Co-authored-by: Cesar Talén <154442565+cesartalen@users.noreply.github.com>
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