Skip to content

Commit 29c0ac8

Browse files
authored
Merge pull request #404 from petalframework/slide_over_id
Allow for multiple instances of the `slide_over` component
2 parents 753da01 + eeb1a47 commit 29c0ac8

File tree

2 files changed

+72
-18
lines changed

2 files changed

+72
-18
lines changed

lib/petal_components/slide_over.ex

+24-18
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ defmodule PetalComponents.SlideOver do
22
use Phoenix.Component
33
alias Phoenix.LiveView.JS
44

5+
attr :id, :string, default: "slide-over"
6+
57
attr(:origin, :string,
68
default: "right",
79
values: ["left", "right", "top", "bottom"],
@@ -41,12 +43,12 @@ defmodule PetalComponents.SlideOver do
4143
~H"""
4244
<div
4345
{@rest}
44-
phx-mounted={!@hide && show_slide_over(@origin)}
45-
phx-remove={hide_slide_over(@origin, @close_slide_over_target)}
46+
phx-mounted={!@hide && show_slide_over(@origin, @id)}
47+
phx-remove={hide_slide_over(@origin, @id, @close_slide_over_target)}
4648
class="hidden pc-slide-over"
47-
id="slide-over"
49+
id={@id}
4850
>
49-
<div id="slide-over-overlay" class="hidden pc-slideover__overlay" aria-hidden="true"></div>
51+
<div id={"#{@id}-overlay"} class="hidden pc-slideover__overlay" aria-hidden="true"></div>
5052
5153
<div
5254
class={["pc-slideover__wrapper", get_margin_classes(@origin), @class]}
@@ -55,22 +57,26 @@ defmodule PetalComponents.SlideOver do
5557
aria-modal="true"
5658
>
5759
<div
58-
id="slide-over-content"
60+
id={"#{@id}-content"}
5961
class={get_classes(@max_width, @origin, @class)}
60-
phx-click-away={@close_on_click_away && hide_slide_over(@origin, @close_slide_over_target)}
61-
phx-window-keydown={@close_on_escape && hide_slide_over(@origin, @close_slide_over_target)}
62+
phx-click-away={
63+
@close_on_click_away && hide_slide_over(@origin, @id, @close_slide_over_target)
64+
}
65+
phx-window-keydown={
66+
@close_on_escape && hide_slide_over(@origin, @id, @close_slide_over_target)
67+
}
6268
phx-key="escape"
6369
>
6470
<!-- Header -->
6571
<div class="pc-slideover__header">
6672
<div class="pc-slideover__header__container">
67-
<div class="pc-slideover__header__text">
73+
<div :if={@title} class="pc-slideover__header__text">
6874
{@title}
6975
</div>
7076
7177
<button
7278
type="button"
73-
phx-click={hide_slide_over(@origin, @close_slide_over_target)}
79+
phx-click={hide_slide_over(@origin, @id, @close_slide_over_target)}
7480
class="pc-slideover__header__button"
7581
>
7682
<div class="sr-only">Close</div>
@@ -90,43 +96,43 @@ defmodule PetalComponents.SlideOver do
9096
"""
9197
end
9298

93-
def show_slide_over(origin) do
99+
def show_slide_over(origin, id \\ "slide-over") do
94100
{start_class, end_class} = get_transition_classes(origin)
95101

96102
%JS{}
97-
|> JS.show(to: "#slide-over")
103+
|> JS.show(to: "##{id}")
98104
|> JS.show(
99-
to: "#slide-over-overlay",
105+
to: "##{id}-overlay",
100106
time: 300,
101107
transition: {"transition-all transform ease-out duration-300", "opacity-0", "opacity-100"}
102108
)
103109
|> JS.show(
104-
to: "#slide-over-content",
110+
to: "##{id}-content",
105111
time: 300,
106112
transition: {"transition-all transform ease-out duration-300", start_class, end_class}
107113
)
108114
|> JS.add_class("overflow-hidden", to: "body")
109-
|> JS.focus_first(to: "#slide-over-content")
115+
|> JS.focus_first(to: "##{id}-content")
110116
end
111117

112118
# The live view that calls <.slide_over> will need to handle the "close_slide_over" event. eg:
113119
# def handle_event("close_slide_over", _, socket) do
114120
# {:noreply, push_patch(socket, to: Routes.moderate_users_path(socket, :index))}
115121
# end
116-
def hide_slide_over(origin, close_slide_over_target \\ nil) do
122+
def hide_slide_over(origin, id \\ "slide-over", close_slide_over_target \\ nil) do
117123
{end_class, start_class} = get_transition_classes(origin)
118124

119125
js =
120126
JS.remove_class("overflow-hidden", to: "body")
121127
|> JS.hide(
122128
transition: {"ease-in duration-200", "opacity-100", "opacity-0"},
123-
to: "#slide-over-overlay"
129+
to: "##{id}-overlay"
124130
)
125131
|> JS.hide(
126132
transition: {"ease-in duration-200", start_class, end_class},
127-
to: "#slide-over-content"
133+
to: "##{id}-content"
128134
)
129-
|> JS.hide(to: "#slide-over", transition: {"duration-200", "", ""})
135+
|> JS.hide(to: "##{id}", transition: {"duration-200", "", ""})
130136

131137
if close_slide_over_target do
132138
JS.push(js, "close_slide_over", target: close_slide_over_target)

test/petal/slide_over_test.exs

+48
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ defmodule PetalComponents.SlideOverTest do
2121
</.slide_over>
2222
""")
2323

24+
assert html =~ "id=\"slide-over\""
25+
assert html =~ "slide-over-overlay"
26+
assert html =~ "slide-over-content"
27+
2428
assert html =~ "data-phx-link"
2529
assert html =~ "phx-click"
2630
assert html =~ "translate-x-0"
@@ -81,6 +85,50 @@ defmodule PetalComponents.SlideOverTest do
8185
assert html =~ "fixed inset-x-0 bottom-0"
8286
end
8387

88+
test "slide_over with default id" do
89+
assigns = %{}
90+
91+
html =
92+
rendered_to_string(~H"""
93+
<.button label="left" link_type="live_patch" to="/live" />
94+
95+
<.slide_over title="SlideOver" origin="left">
96+
<div class="gap-5 text-sm">
97+
<.form_label label="Add some text here." />
98+
<div class="flex justify-end">
99+
<.button label="close" phx-click={PetalComponents.SlideOver.hide_slide_over("left")} />
100+
</div>
101+
</div>
102+
</.slide_over>
103+
""")
104+
105+
assert html =~ "id=\"slide-over\""
106+
assert html =~ "slide-over-overlay"
107+
assert html =~ "slide-over-content"
108+
end
109+
110+
test "slide_over with custom id" do
111+
assigns = %{}
112+
113+
html =
114+
rendered_to_string(~H"""
115+
<.button label="left" link_type="live_patch" to="/live" />
116+
117+
<.slide_over id="bert" title="SlideOver" origin="left">
118+
<div class="gap-5 text-sm">
119+
<.form_label label="Add some text here." />
120+
<div class="flex justify-end">
121+
<.button label="close" phx-click={PetalComponents.SlideOver.hide_slide_over("left")} />
122+
</div>
123+
</div>
124+
</.slide_over>
125+
""")
126+
127+
assert html =~ "id=\"bert\""
128+
assert html =~ "bert-overlay"
129+
assert html =~ "bert-content"
130+
end
131+
84132
test "dark mode" do
85133
assigns = %{}
86134

0 commit comments

Comments
 (0)