Skip to content

Commit

Permalink
Copy of Phoenix.Component.focus_wrap that ensures sorted attributes t…
Browse files Browse the repository at this point in the history
…o aid testing
  • Loading branch information
ArthurClemens committed Sep 13, 2024
1 parent 05f5394 commit 32b5060
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 100 deletions.
42 changes: 29 additions & 13 deletions lib/component.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7132,13 +7132,13 @@ defmodule PrimerLive.Component do
|> assign(:focus_wrap_attrs, focus_wrap_attrs)

~H"""
<.focus_wrap {@focus_wrap_attrs}>
<.pl_focus_wrap {@focus_wrap_attrs}>
<ul {@prompt_attrs}>
<%= for item <- @item do %>
<%= @render_item.(item) %>
<% end %>
</ul>
</.focus_wrap>
</.pl_focus_wrap>
"""
end

Expand Down Expand Up @@ -7824,7 +7824,7 @@ defmodule PrimerLive.Component do
<div {@touch_layer_attrs}></div>
<div class={@classes.menu}>
<div {@menu_container_attrs}>
<.focus_wrap {@focus_wrap_attrs}>
<.pl_focus_wrap {@focus_wrap_attrs}>
<%= if not is_nil(@menu_title) do %>
<header class={@classes.header}>
<h3 class={@classes.menu_title}><%= @menu_title %></h3>
Expand Down Expand Up @@ -7883,7 +7883,7 @@ defmodule PrimerLive.Component do
</div>
<% end %>
<% end %>
</.focus_wrap>
</.pl_focus_wrap>
</div>
</div>
</div>
Expand Down Expand Up @@ -8145,9 +8145,9 @@ defmodule PrimerLive.Component do
<div class={@classes.menu}>
<div {@menu_container_attrs}>
<div class={@classes.menu_list}>
<.focus_wrap {@focus_wrap_attrs}>
<.pl_focus_wrap {@focus_wrap_attrs}>
<%= render_slot(@inner_block) %>
</.focus_wrap>
</.pl_focus_wrap>
</div>
</div>
</div>
Expand Down Expand Up @@ -11496,7 +11496,7 @@ defmodule PrimerLive.Component do
</.dialog>
```
Dialog content is automatically wrapped inside a `Phoenix.Component.focus_wrap/1` so that navigating with Tab won't leave the dialog.
Dialog content is automatically wrapped inside a `Phoenix.Component.pl_focus_wrap/1` so that navigating with Tab won't leave the dialog.
```
<.dialog is_backdrop is_modal>
Expand Down Expand Up @@ -11732,7 +11732,7 @@ defmodule PrimerLive.Component do
<div {@backdrop_attrs} />
<% end %>
<div {@touch_layer_attrs}></div>
<.focus_wrap {@focus_wrap_attrs}>
<.pl_focus_wrap {@focus_wrap_attrs}>
<.box {@content_attrs}>
<:header :if={@header_title && @header_title !== []} class={@classes.header}>
<.button {@close_button_attrs}>
Expand All @@ -11741,7 +11741,7 @@ defmodule PrimerLive.Component do
</:header>
<%= render_slot(@inner_block) %>
</.box>
</.focus_wrap>
</.pl_focus_wrap>
</div>
"""
end
Expand Down Expand Up @@ -12161,9 +12161,9 @@ defmodule PrimerLive.Component do
<%= render_slot(@inner_block) %>
<%= if @body && @body !== [] do %>
<div {@body_attrs}>
<.focus_wrap {@focus_wrap_attrs}>
<.pl_focus_wrap {@focus_wrap_attrs}>
<%= render_slot(@body) %>
</.focus_wrap>
</.pl_focus_wrap>
</div>
<% end %>
</div>
Expand Down Expand Up @@ -12254,9 +12254,9 @@ defmodule PrimerLive.Component do

~H"""
<div {@content_attrs}>
<.focus_wrap {@focus_wrap_attrs}>
<.pl_focus_wrap {@focus_wrap_attrs}>
<%= render_slot(@inner_block) %>
</.focus_wrap>
</.pl_focus_wrap>
</div>
"""
end
Expand Down Expand Up @@ -13461,4 +13461,20 @@ defmodule PrimerLive.Component do
<% end %>
"""
end

# Copy of Phoenix.Component.focus_wrap that ensures sorted attributes to aid testing

defp pl_focus_wrap(assigns) do
assigns = assigns |> assign(:attrs, AttributeHelpers.assigns_to_attributes_sorted(assigns, [
id: assigns[:id], "phx-hook": "Phoenix.FocusWrap"
]))

~H"""
<div {@attrs}>
<span id={"#{@id}-start"} tabindex="0" aria-hidden="true"></span>
<%= render_slot(@inner_block) %>
<span id={"#{@id}-end"} tabindex="0" aria-hidden="true"></span>
</div>
"""
end
end
12 changes: 6 additions & 6 deletions lib/helpers/attribute_helpers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -845,10 +845,10 @@ defmodule PrimerLive.Helpers.AttributeHelpers do
focus_wrap_attrs =
append_attributes([
[
id: focus_wrap_id,
"data-focuswrap": "",
"phx-window-keydown": assigns.is_escapable && PromptHelpers.cancel_prompt(id),
"phx-key": "Escape"
id: focus_wrap_id,
"phx-key": "Escape",
"phx-window-keydown": assigns.is_escapable && PromptHelpers.cancel_prompt(id)
]
])

Expand All @@ -862,11 +862,11 @@ defmodule PrimerLive.Helpers.AttributeHelpers do
toggle_attrs =
append_attributes(toggle_rest, [
[
class: toggle_class,
"aria-haspopup": "true",
"aria-owns": focus_wrap_id,
type: "button",
"phx-click": Keyword.get(toggle_rest, :"phx-click", PromptHelpers.toggle_prompt(id))
class: toggle_class,
"phx-click": Keyword.get(toggle_rest, :"phx-click", PromptHelpers.toggle_prompt(id)),
type: "button"
]
])

Expand Down
18 changes: 9 additions & 9 deletions test/components/action_menu_test.exs

Large diffs are not rendered by default.

40 changes: 20 additions & 20 deletions test/components/dialog_test.exs

Large diffs are not rendered by default.

26 changes: 13 additions & 13 deletions test/components/drawer_content_deprecated_test.exs

Large diffs are not rendered by default.

28 changes: 14 additions & 14 deletions test/components/drawer_test.exs

Large diffs are not rendered by default.

18 changes: 9 additions & 9 deletions test/components/dropdown_test.exs

Large diffs are not rendered by default.

28 changes: 14 additions & 14 deletions test/components/select_menu_test.exs

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions test/components/subnav_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ defmodule PrimerLive.Components.SubnavTest do
""")
|> format_html() ==
"""
<div class="subnav"><div class="subnav-search-context float-left"><div data-cancel="[[&quot;exec&quot;,{&quot;attr&quot;:&quot;data-close&quot;}]]" data-close="[[&quot;remove_class&quot;,{&quot;names&quot;:[&quot;is-showing&quot;],&quot;to&quot;:&quot;#querty&quot;}],[&quot;remove_class&quot;,{&quot;time&quot;:130,&quot;names&quot;:[&quot;is-open&quot;],&quot;to&quot;:&quot;#querty&quot;,&quot;transition&quot;:[[&quot;duration-130&quot;],[&quot;&quot;],[&quot;&quot;]]}],[&quot;pop_focus&quot;,{}]]" data-isescapable="" data-isfast="" data-ismenu="" data-open="[[&quot;add_class&quot;,{&quot;names&quot;:[&quot;is-open&quot;],&quot;to&quot;:&quot;#querty&quot;}],[&quot;focus_first&quot;,{&quot;to&quot;:&quot;#querty [data-content]&quot;}],[&quot;add_class&quot;,{&quot;time&quot;:30,&quot;names&quot;:[&quot;is-showing&quot;],&quot;to&quot;:&quot;#querty&quot;,&quot;transition&quot;:[[&quot;duration-30&quot;],[&quot;&quot;],[&quot;&quot;]]}]]" data-prompt="" id="querty" phx-hook="Prompt"><button aria-haspopup="true" aria-owns="focus-wrap-querty" class="btn" phx-click="[[&quot;dispatch&quot;,{&quot;to&quot;:&quot;#querty&quot;,&quot;event&quot;:&quot;prompt:toggle&quot;}]]" type="button">Menu<div class="dropdown-caret"></div></button><div data-touch="" phx-click="[[&quot;exec&quot;,{&quot;to&quot;:&quot;#querty&quot;,&quot;attr&quot;:&quot;data-cancel&quot;}]]"></div><div class="SelectMenu"><div aria-role="menu" class="SelectMenu-modal" data-content=""><div id="focus-wrap-querty" phx-hook="Phoenix.FocusWrap" phx-window-keydown="[[&quot;exec&quot;,{&quot;to&quot;:&quot;#querty&quot;,&quot;attr&quot;:&quot;data-cancel&quot;}]]" phx-key="Escape" data-focuswrap=""><span id="focus-wrap-querty-start" tabindex="0" aria-hidden="true"></span><div class="SelectMenu-list"><button class="SelectMenu-item" role="menuitem">Item 1</button><button class="SelectMenu-item" role="menuitem">Item 2</button><button class="SelectMenu-item" role="menuitem">Item 3</button></div><span id="focus-wrap-querty-end" tabindex="0" aria-hidden="true"></span></div></div></div></div></div><div class="subnav-search float-left"><input class="FormControl-input FormControl-medium" type="search" /><svg class="octicon subnav-search-icon" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">STRIPPED_SVG_PATHS</svg></div></div>
<div class="subnav"><div class="subnav-search-context float-left"><div data-cancel="[[&quot;exec&quot;,{&quot;attr&quot;:&quot;data-close&quot;}]]" data-close="[[&quot;remove_class&quot;,{&quot;names&quot;:[&quot;is-showing&quot;],&quot;to&quot;:&quot;#querty&quot;}],[&quot;remove_class&quot;,{&quot;time&quot;:130,&quot;names&quot;:[&quot;is-open&quot;],&quot;to&quot;:&quot;#querty&quot;,&quot;transition&quot;:[[&quot;duration-130&quot;],[&quot;&quot;],[&quot;&quot;]]}],[&quot;pop_focus&quot;,{}]]" data-isescapable="" data-isfast="" data-ismenu="" data-open="[[&quot;add_class&quot;,{&quot;names&quot;:[&quot;is-open&quot;],&quot;to&quot;:&quot;#querty&quot;}],[&quot;focus_first&quot;,{&quot;to&quot;:&quot;#querty [data-content]&quot;}],[&quot;add_class&quot;,{&quot;time&quot;:30,&quot;names&quot;:[&quot;is-showing&quot;],&quot;to&quot;:&quot;#querty&quot;,&quot;transition&quot;:[[&quot;duration-30&quot;],[&quot;&quot;],[&quot;&quot;]]}]]" data-prompt="" id="querty" phx-hook="Prompt"><button aria-haspopup="true" aria-owns="focus-wrap-querty" class="btn" phx-click="[[&quot;dispatch&quot;,{&quot;to&quot;:&quot;#querty&quot;,&quot;event&quot;:&quot;prompt:toggle&quot;}]]" type="button">Menu<div class="dropdown-caret"></div></button><div data-touch="" phx-click="[[&quot;exec&quot;,{&quot;to&quot;:&quot;#querty&quot;,&quot;attr&quot;:&quot;data-cancel&quot;}]]"></div><div class="SelectMenu"><div aria-role="menu" class="SelectMenu-modal" data-content=""><div data-focuswrap="" id="focus-wrap-querty" phx-key="Escape" phx-window-keydown="[[&quot;exec&quot;,{&quot;to&quot;:&quot;#querty&quot;,&quot;attr&quot;:&quot;data-cancel&quot;}]]"><span id="focus-wrap-querty-start" tabindex="0" aria-hidden="true"></span><div class="SelectMenu-list"><button class="SelectMenu-item" role="menuitem">Item 1</button><button class="SelectMenu-item" role="menuitem">Item 2</button><button class="SelectMenu-item" role="menuitem">Item 3</button></div><span id="focus-wrap-querty-end" tabindex="0" aria-hidden="true"></span></div></div></div></div></div><div class="subnav-search float-left"><input class="FormControl-input FormControl-medium" type="search" /><svg class="octicon subnav-search-icon" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">STRIPPED_SVG_PATHS</svg></div></div>
"""
|> format_html()
rescue
Expand Down Expand Up @@ -150,7 +150,7 @@ defmodule PrimerLive.Components.SubnavTest do
""")
|> format_html() ==
"""
<div class="subnav my-links-subnav"><nav class="subnav-links my-subnav-links"><a href="#url" class="subnav-item" aria-current="page">Link 1</a><a href="#url" data-phx-link="redirect" data-phx-link-state="push" class="subnav-item">Link 2</a></nav></div><div class="subnav my-search-subnav"><div class="subnav-search-context float-left my-subnav-search-context"><div data-cancel="[[&quot;exec&quot;,{&quot;attr&quot;:&quot;data-close&quot;}]]" data-close="[[&quot;remove_class&quot;,{&quot;names&quot;:[&quot;is-showing&quot;],&quot;to&quot;:&quot;#querty&quot;}],[&quot;remove_class&quot;,{&quot;time&quot;:130,&quot;names&quot;:[&quot;is-open&quot;],&quot;to&quot;:&quot;#querty&quot;,&quot;transition&quot;:[[&quot;duration-130&quot;],[&quot;&quot;],[&quot;&quot;]]}],[&quot;pop_focus&quot;,{}]]" data-isescapable="" data-isfast="" data-ismenu="" data-open="[[&quot;add_class&quot;,{&quot;names&quot;:[&quot;is-open&quot;],&quot;to&quot;:&quot;#querty&quot;}],[&quot;focus_first&quot;,{&quot;to&quot;:&quot;#querty [data-content]&quot;}],[&quot;add_class&quot;,{&quot;time&quot;:30,&quot;names&quot;:[&quot;is-showing&quot;],&quot;to&quot;:&quot;#querty&quot;,&quot;transition&quot;:[[&quot;duration-30&quot;],[&quot;&quot;],[&quot;&quot;]]}]]" data-prompt="" id="querty" phx-hook="Prompt"><button aria-haspopup="true" aria-owns="focus-wrap-querty" class="btn" phx-click="[[&quot;dispatch&quot;,{&quot;to&quot;:&quot;#querty&quot;,&quot;event&quot;:&quot;prompt:toggle&quot;}]]" type="button">Menu<div class="dropdown-caret"></div></button><div data-touch="" phx-click="[[&quot;exec&quot;,{&quot;to&quot;:&quot;#querty&quot;,&quot;attr&quot;:&quot;data-cancel&quot;}]]"></div><div class="SelectMenu"><div aria-role="menu" class="SelectMenu-modal" data-content=""><div id="focus-wrap-querty" phx-hook="Phoenix.FocusWrap" phx-window-keydown="[[&quot;exec&quot;,{&quot;to&quot;:&quot;#querty&quot;,&quot;attr&quot;:&quot;data-cancel&quot;}]]" phx-key="Escape" data-focuswrap=""><span id="focus-wrap-querty-start" tabindex="0" aria-hidden="true"></span><div class="SelectMenu-list"><button class="SelectMenu-item" role="menuitem">Item 1</button><button class="SelectMenu-item" role="menuitem">Item 2</button><button class="SelectMenu-item" role="menuitem">Item 3</button></div><span id="focus-wrap-querty-end" tabindex="0" aria-hidden="true"></span></div></div></div></div></div><div class="subnav-search float-left my-subnav-search"><input class="FormControl-input FormControl-medium" id="site-search" name="site-search" type="search" /><svg class="octicon subnav-search-icon" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">STRIPPED_SVG_PATHS</svg></div></div>
<div class="subnav my-links-subnav"><nav class="subnav-links my-subnav-links"><a href="#url" class="subnav-item" aria-current="page">Link 1</a><a href="#url" data-phx-link="redirect" data-phx-link-state="push" class="subnav-item">Link 2</a></nav></div><div class="subnav my-search-subnav"><div class="subnav-search-context float-left my-subnav-search-context"><div data-cancel="[[&quot;exec&quot;,{&quot;attr&quot;:&quot;data-close&quot;}]]" data-close="[[&quot;remove_class&quot;,{&quot;names&quot;:[&quot;is-showing&quot;],&quot;to&quot;:&quot;#querty&quot;}],[&quot;remove_class&quot;,{&quot;time&quot;:130,&quot;names&quot;:[&quot;is-open&quot;],&quot;to&quot;:&quot;#querty&quot;,&quot;transition&quot;:[[&quot;duration-130&quot;],[&quot;&quot;],[&quot;&quot;]]}],[&quot;pop_focus&quot;,{}]]" data-isescapable="" data-isfast="" data-ismenu="" data-open="[[&quot;add_class&quot;,{&quot;names&quot;:[&quot;is-open&quot;],&quot;to&quot;:&quot;#querty&quot;}],[&quot;focus_first&quot;,{&quot;to&quot;:&quot;#querty [data-content]&quot;}],[&quot;add_class&quot;,{&quot;time&quot;:30,&quot;names&quot;:[&quot;is-showing&quot;],&quot;to&quot;:&quot;#querty&quot;,&quot;transition&quot;:[[&quot;duration-30&quot;],[&quot;&quot;],[&quot;&quot;]]}]]" data-prompt="" id="querty" phx-hook="Prompt"><button aria-haspopup="true" aria-owns="focus-wrap-querty" class="btn" phx-click="[[&quot;dispatch&quot;,{&quot;to&quot;:&quot;#querty&quot;,&quot;event&quot;:&quot;prompt:toggle&quot;}]]" type="button">Menu<div class="dropdown-caret"></div></button><div data-touch="" phx-click="[[&quot;exec&quot;,{&quot;to&quot;:&quot;#querty&quot;,&quot;attr&quot;:&quot;data-cancel&quot;}]]"></div><div class="SelectMenu"><div aria-role="menu" class="SelectMenu-modal" data-content=""><div data-focuswrap="" id="focus-wrap-querty" phx-key="Escape" phx-window-keydown="[[&quot;exec&quot;,{&quot;to&quot;:&quot;#querty&quot;,&quot;attr&quot;:&quot;data-cancel&quot;}]]"><span id="focus-wrap-querty-start" tabindex="0" aria-hidden="true"></span><div class="SelectMenu-list"><button class="SelectMenu-item" role="menuitem">Item 1</button><button class="SelectMenu-item" role="menuitem">Item 2</button><button class="SelectMenu-item" role="menuitem">Item 3</button></div><span id="focus-wrap-querty-end" tabindex="0" aria-hidden="true"></span></div></div></div></div></div><div class="subnav-search float-left my-subnav-search"><input class="FormControl-input FormControl-medium" id="site-search" name="site-search" type="search" /><svg class="octicon subnav-search-icon" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">STRIPPED_SVG_PATHS</svg></div></div>
"""
|> format_html()
rescue
Expand Down

0 comments on commit 32b5060

Please sign in to comment.