Skip to content

Commit

Permalink
Refactor small annoyances with current code (#6)
Browse files Browse the repository at this point in the history
* WIP

* Remove trailing whitespaces messing up formatting

* WIP
  • Loading branch information
thiagomajesk authored Mar 28, 2023
1 parent 21063e3 commit 9220e3f
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 50 deletions.
71 changes: 32 additions & 39 deletions lib/swish/dialog.ex
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
defmodule Swish.Dialog.Transitions do
@moduledoc false
defstruct [:show_content, :hide_content, :show_backdrop, :hide_backdrop]
end

defmodule Swish.Dialog do
@moduledoc """
A dialog is a window overlaid on either the primary window or another dialog window.
Expand All @@ -24,9 +19,9 @@ defmodule Swish.Dialog do
<Swish.Dialog.backdrop dialog={dialog}>
<Swish.Dialog.content dialog={dialog}>
<Swish.Dialog.title dialog={dialog}>Welcome to Swish!</Swish.Dialog.title>
<Swish.Dialog.description dialog={dialog}>Swish is a UI toolkit for busy developers</Swish.Dialog.description>
<Swish.Dialog.description dialog={dialog}>Swish is a UI toolkit for busy developers</Swish.Dialog.description>
<p>Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum sint consectetur cupidatat.</p>
</Swish.Dialog.content>
</Swish.Dialog.content>
</Swish.Dialog.backdrop>
</Swish.Dialog.portal>
</Swish.Dialog.root>
Expand Down Expand Up @@ -55,25 +50,23 @@ defmodule Swish.Dialog do
alias Phoenix.LiveView.JS

@doc false
def new() do
def new(attrs \\ %{}) do
js_module = Swish.JS.dynamic!()
dialog_id = System.unique_integer([:positive, :monotonic])
portal_id = System.unique_integer()

%Dialog{
id: "dialog-#{dialog_id}",
portal_id: "portal-#{portal_id}",
id: attrs[:id] || Swish.EL.new_id("dialog"),
open: attrs[:open] || false,
static: attrs[:static] || false,
open_delay: attrs[:open_delay] || 200,
close_delay: attrs[:close_delay] || 200,
portal_id: Swish.EL.new_id("portal"),
js_show: Function.capture(js_module, :show_dialog, 2),
js_hide: Function.capture(js_module, :hide_dialog, 2),
open: false,
static: false,
open_delay: 200,
close_delay: 200,
transitions: %Dialog.Transitions{}
transitions: attrs[:transitions] || %Dialog.Transitions{}
}
end

attr(:id, :string, required: false)
attr(:id, :string, default: nil)
attr(:open, :boolean, default: false)
attr(:static, :boolean, default: false)
attr(:open_delay, :integer, default: 200)
Expand All @@ -88,14 +81,14 @@ defmodule Swish.Dialog do
def root(assigns) do
assigns =
assign_new(assigns, :dialog, fn ->
%{
Dialog.new()
| open: assigns.open,
static: assigns.static,
open_delay: assigns.open_delay,
close_delay: assigns.close_delay,
transitions: assigns.transitions
}
Dialog.new(%{
id: assigns.id,
open: assigns.open,
static: assigns.static,
open_delay: assigns.open_delay,
close_delay: assigns.close_delay,
transitions: assigns.transitions
})
end)

~H"""
Expand All @@ -111,10 +104,10 @@ defmodule Swish.Dialog do
def trigger(assigns) do
assigns =
assign(assigns, :attrs, %{
"aria-haspopup" => "dialog",
"phx-click" => JS.exec("data-show", to: "##{assigns.dialog.portal_id}"),
"id" => "#{assigns.dialog.id}-trigger",
"data-state" => open_to_state(assigns.dialog)
aria_haspopup: "dialog",
phx_click: JS.exec("data-show", to: "##{assigns.dialog.portal_id}"),
id: Swish.EL.suffix_id(assigns.dialog, "trigger"),
data_state: open_to_state(assigns.dialog)
})

~H"""
Expand All @@ -127,7 +120,7 @@ defmodule Swish.Dialog do
attr(:rest, :global)

def backdrop(assigns) do
assigns = assign(assigns, id: "#{assigns.dialog.id}-backdrop")
assigns = assign(assigns, id: Swish.EL.suffix_id(assigns.dialog, "backdrop"))

~H"""
<div
Expand All @@ -148,9 +141,9 @@ defmodule Swish.Dialog do
def close(assigns) do
assigns =
assign(assigns, :attrs, %{
"aria-label" => "Close",
"phx-click" => hide(assigns.dialog),
"id" => "#{assigns.dialog.id}-close"
aria_label: "Close",
phx_click: hide(assigns.dialog),
id: Swish.EL.suffix_id(assigns.dialog, "close")
})

~H"""
Expand All @@ -163,7 +156,7 @@ defmodule Swish.Dialog do
slot(:inner_block, required: true)

def content(assigns) do
assigns = assign(assigns, id: "#{assigns.dialog.id}-content")
assigns = assign(assigns, id: Swish.EL.suffix_id(assigns.dialog, "content"))

~H"""
<.focus_wrap
Expand All @@ -172,8 +165,8 @@ defmodule Swish.Dialog do
data-hide={unless @dialog.static, do: hide(@dialog)}
phx-click-away={JS.exec("data-hide")}
phx-window-keydown={JS.exec("data-hide")}
aria-labelledby={"#{@dialog.id}-title"}
aria-describedby={"#{@dialog.id}-description"}
aria-labelledby={Swish.EL.suffix_id(@dialog, "title")}
aria-describedby={Swish.EL.suffix_id(@dialog, "description")}
data-state={open_to_state(@dialog)}
role="dialog"
aria-modal="true"
Expand All @@ -192,7 +185,7 @@ defmodule Swish.Dialog do
slot(:inner_block, required: true)

def title(assigns) do
assigns = assign(assigns, id: "#{assigns.dialog.id}-title")
assigns = assign(assigns, id: Swish.EL.suffix_id(assigns.dialog, "title"))

~H"""
<.dynamic_tag id={@id} name={@as} {@rest}>
Expand All @@ -207,7 +200,7 @@ defmodule Swish.Dialog do
slot(:inner_block, required: true)

def description(assigns) do
assigns = assign(assigns, id: "#{assigns.dialog.id}-description")
assigns = assign(assigns, id: Swish.EL.suffix_id(assigns.dialog, "description"))

~H"""
<.dynamic_tag id={@id} name={@as} {@rest}>
Expand Down
7 changes: 7 additions & 0 deletions lib/swish/dialog/transitions.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
defmodule Swish.Dialog.Transitions do
@moduledoc """
Describes the available transitions for a dialog.
"""

defstruct [:show_content, :hide_content, :show_backdrop, :hide_backdrop]
end
17 changes: 17 additions & 0 deletions lib/swish/el.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
defmodule Swish.EL do
@moduledoc false

def new_id(prefix, escaped \\ false)
def new_id(prefix, true), do: "##{prefix}-#{System.unique_integer([:positive])}"
def new_id(prefix, false), do: "#{prefix}-#{System.unique_integer([:positive])}"

def get_id(el, escaped \\ false)
def get_id(%{id: id}, true), do: "##{id}"
def get_id(%{id: id}, false), do: "#{id}"

def suffix_id(el, suffix, escaped \\ false)
def suffix_id(%{id: id}, suffix, true), do: "##{id}-#{suffix}"
def suffix_id(%{id: id}, suffix, false), do: "#{id}-#{suffix}"

def event(name), do: "swish:#{name}"
end
30 changes: 19 additions & 11 deletions lib/swish/js.ex
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,34 @@ defmodule Swish.JS do
@behaviour Swish.JS

def show_dialog(js \\ %JS{}, %Swish.Dialog{} = dialog) do
trigger_target = Swish.EL.suffix_id(dialog, "trigger", true)
backdrop_target = Swish.EL.suffix_id(dialog, "backdrop", true)
content_target = Swish.EL.suffix_id(dialog, "content", true)

js
|> JS.dispatch("portal:open", to: "##{dialog.portal_id}")
|> JS.set_attribute({"data-state", "open"}, to: "##{dialog.id}-trigger")
|> JS.set_attribute({"data-state", "open"}, to: "##{dialog.id}-backdrop")
|> JS.set_attribute({"data-state", "open"}, to: "##{dialog.id}-content")
|> JS.set_attribute({"aria-expanded", "true"}, to: "##{dialog.id}-trigger")
|> JS.set_attribute({"data-state", "open"}, to: trigger_target)
|> JS.set_attribute({"data-state", "open"}, to: backdrop_target)
|> JS.set_attribute({"data-state", "open"}, to: content_target)
|> JS.set_attribute({"aria-expanded", "true"}, to: trigger_target)
|> JS.show(
to: "##{dialog.id}-backdrop",
to: backdrop_target,
transition: dialog.transitions.show_backdrop,
time: dialog.open_delay
)
|> JS.show(
to: "##{dialog.id}-content",
to: content_target,
transition: dialog.transitions.show_content,
time: dialog.open_delay
)
|> JS.focus_first(to: "##{dialog.id}-content")
|> JS.focus_first(to: content_target)
end

def hide_dialog(js \\ %JS{}, %Swish.Dialog{} = dialog) do
trigger_target = Swish.EL.suffix_id(dialog, "trigger", true)
backdrop_target = Swish.EL.suffix_id(dialog, "backdrop", true)
content_target = Swish.EL.suffix_id(dialog, "content", true)

js
|> JS.pop_focus()
|> JS.hide(
Expand All @@ -53,10 +61,10 @@ defmodule Swish.JS do
transition: dialog.transitions.hide_content,
time: dialog.close_delay
)
|> JS.set_attribute({"data-state", "closed"}, to: "##{dialog.id}-trigger")
|> JS.set_attribute({"data-state", "closed"}, to: "##{dialog.id}-backdrop")
|> JS.set_attribute({"data-state", "closed"}, to: "##{dialog.id}-content")
|> JS.set_attribute({"aria-expanded", "false"}, to: "##{dialog.id}-trigger")
|> JS.set_attribute({"data-state", "closed"}, to: trigger_target)
|> JS.set_attribute({"data-state", "closed"}, to: backdrop_target)
|> JS.set_attribute({"data-state", "closed"}, to: content_target)
|> JS.set_attribute({"aria-expanded", "false"}, to: trigger_target)
|> JS.dispatch("portal:close", to: "##{dialog.portal_id}")
end

Expand Down

0 comments on commit 9220e3f

Please sign in to comment.