Skip to content

Commit fc5ccdd

Browse files
committed
[DREAM-729] Lazy loaded Action menu positioning is incorrect when opened at the bottom of the page.
https://community.openproject.org/wp/DREAM-729 defer
1 parent e3ddebe commit fc5ccdd

6 files changed

Lines changed: 35 additions & 0 deletions

File tree

.changeset/silly-lights-fall.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@openproject/primer-view-components': patch
3+
---
4+
5+
Fix lazy loaded action-menu positioning when opened at the bottom of the page.

app/components/primer/alpha/action_menu/action_menu_element.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ export class ActionMenuElement extends HTMLElement {
472472
#handleIncludeFragmentReplaced() {
473473
this.#firstItem?.focus()
474474
this.#softDisableItems()
475+
this.overlay?.update()
475476

476477
// async items have loaded, so component is ready
477478
this.setAttribute('data-ready', 'true')

app/controllers/primer/view_components/action_menu_controller.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class ActionMenuController < ApplicationController
1010
def landing; end
1111

1212
def deferred
13+
sleep params[:delay].to_f if params[:delay].present?
1314
render "primer/view_components/action_menu/deferred"
1415
end
1516

previews/primer/alpha/action_menu_preview.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,13 @@ def with_deferred_content(nest_in_sub_menu: false)
310310
render_with_template(locals: { nest_in_sub_menu: nest_in_sub_menu })
311311
end
312312

313+
# @label With deferred content near the bottom of the viewport
314+
#
315+
# @hidden
316+
def with_deferred_content_near_bottom_of_viewport
317+
render_with_template
318+
end
319+
313320
# @label With deferred preloaded content
314321
#
315322
def with_deferred_preloaded_content
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<%# The invoker is pinned near the bottom of the viewport, leaving enough room for the loading %>
2+
<%# spinner placeholder to fit below it but not enough for the full deferred content, reproducing %>
3+
<%# the scenario from DREAM-729. The `delay` param forces the fragment response to arrive after the %>
4+
<%# overlay has already been positioned using the placeholder's size, instead of racing the fetch %>
5+
<%# against the initial position calculation. %>
6+
<div style="position: fixed; bottom: 100px; right: 0;">
7+
<%= render(Primer::Alpha::ActionMenu.new(menu_id: "deferred-bottom", src: primer_view_components.action_menu_deferred_path(delay: 0.3))) do |menu| %>
8+
<% menu.with_show_button { "Menu with deferred content" } %>
9+
<% end %>
10+
</div>

test/system/alpha/action_menu_test.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,17 @@ def test_deferred_loading_on_keydown
890890
assert_equal page.evaluate_script("document.activeElement").text, "Copy link"
891891
end
892892

893+
def test_deferred_loading_overlay_positioned_within_viewport
894+
visit_preview(:with_deferred_content_near_bottom_of_viewport)
895+
click_on_invoker_button
896+
897+
# Wait for lazy content to load
898+
assert_selector "action-menu ul li", text: "Copy link"
899+
900+
overlay = find("anchored-position").native.node
901+
assert overlay.in_viewport?, "Overlay should be positioned within the viewport after deferred content loads"
902+
end
903+
893904
def test_deferred_dialog_opens
894905
visit_preview(:with_deferred_content)
895906

0 commit comments

Comments
 (0)