popover: Add offset and optional anchor-aligned arrows - #3145
Merged
Merged
Conversation
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.
Description
Popover now supports
anchor + offset + arrow: callers can adjust the trigger gap and enable an arrow aligned to any of the eight existing anchors, includingTopCenterandBottomCenter. The arrow follows the anchor's edge and leading/center/trailing alignment, with an inset to avoid rounded corners.arrowdefaults to false; spacing and arrows preserve the selected anchor and its window-clamping behavior.Correct the documentation:
Anchor::TopLeftnames the popup's own anchor and opens below the trigger. Positioning measures the actual trigger rectangle and uses current-frame bounds when the trigger moves. The compact Anchor story demonstrates all eight anchors with small trigger buttons and a shared Arrow checkbox, unchecked by default. English and Chinese docs are updated.Public API
gpui-component
popover::Popover::offset(self, offset: impl Into<Pixels>) -> Self— set the trigger-to-surface gap, or trigger-to-arrow-tip gap; defaults to 0.25rem.popover::Popover::arrow(self, arrow: bool) -> Self— show the themed arrow aligned to the existing anchor; defaults to false.gpui-base
Popover::offset(self, offset: Pixels) -> SelfandPopup::offset(self, offset: Pixels) -> Self— set the outward gap for the selected anchor; defaults to zero.Popover::on_position(self, callback: impl Fn(ResolvedPosition, Bounds<Pixels>) + 'static) -> SelfandPopup::on_position(self, callback: impl Fn(ResolvedPosition, Bounds<Pixels>) + 'static) -> Self— observe resolved popup and trigger geometry before content prepaint for custom presentation.Positioner::on_position(self, callback: impl Fn(ResolvedPosition) + 'static) -> Self— observe resolved geometry before children prepaint.No new Popover placement/alignment API, enum re-exports, JavaScript methods, or TypeScript declarations. Base supplies geometry; Component draws the arrow.
Breaking Changes
The existing horizontal-center anchors now attach to the corresponding trigger edge instead of using the old top-left fallback:
The six top/bottom anchors retain their default positioning. Anchors clamp into the window without flipping.
How to Test
cargo test -p gpui-base -p gpui-component --lib --locked— 1,548 tests passed.cargo clippy -p gpui-base -p gpui-component --lib --lockedcargo build -p gpui-component-story -p gpui-base-examples --bins --lockedcargo run -p gpui-component-story -- Popover: in the final Anchor section, toggle the Arrow checkbox and click each anchor button. Check leading, center, and trailing arrow alignment and spacing, with and without arrows.cargo run -p gpui-base-examples -- popover: exercise the unstyled popover lifecycle.Regression coverage includes eight anchor positions, explicit gaps, moving triggers, no implicit flipping, arrow anchor alignment, joins, and default positioning. Native testing was on Linux; macOS and Windows were not tested locally.
Checklist