Skip to content

Commit b7f543f

Browse files
authored
Merge pull request opf#478 from opf/bug/dream-729-lazy-loaded-action-menu-positioning-is-incorrect-when-opened-at-the-bottom-of-the-page
[DREAM-729] Lazy loaded Action menu positioning is incorrect when opened at the bottom of the page.
2 parents e3ddebe + daa08dc commit b7f543f

8 files changed

Lines changed: 61 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>

static/info_arch.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1438,6 +1438,19 @@
14381438
]
14391439
}
14401440
},
1441+
{
1442+
"preview_path": "primer/alpha/action_menu/with_deferred_content_near_bottom_of_viewport",
1443+
"name": "with_deferred_content_near_bottom_of_viewport",
1444+
"snapshot": "false",
1445+
"skip_rules": {
1446+
"wont_fix": [
1447+
"region"
1448+
],
1449+
"will_fix": [
1450+
"color-contrast"
1451+
]
1452+
}
1453+
},
14411454
{
14421455
"preview_path": "primer/alpha/action_menu/with_deferred_preloaded_content",
14431456
"name": "with_deferred_preloaded_content",

static/previews.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,19 @@
632632
]
633633
}
634634
},
635+
{
636+
"preview_path": "primer/alpha/action_menu/with_deferred_content_near_bottom_of_viewport",
637+
"name": "with_deferred_content_near_bottom_of_viewport",
638+
"snapshot": "false",
639+
"skip_rules": {
640+
"wont_fix": [
641+
"region"
642+
],
643+
"will_fix": [
644+
"color-contrast"
645+
]
646+
}
647+
},
635648
{
636649
"preview_path": "primer/alpha/action_menu/with_deferred_preloaded_content",
637650
"name": "with_deferred_preloaded_content",

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)