Skip to content

Commit

Permalink
feat: add hability to customize group toast classes
Browse files Browse the repository at this point in the history
  • Loading branch information
nelsonmestevao committed Jun 10, 2024
1 parent 7737fed commit 3f73c8c
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 77 deletions.
2 changes: 1 addition & 1 deletion .formatter.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
plugins: [Phoenix.LiveView.HTMLFormatter, Styler],
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"],
subdirectories: ["demo"],
import_deps: [:phoenix_live_view],
import_deps: [:phoenix, :phoenix_live_view],
locals_without_parens: [
attr: 2,
attr: 3,
Expand Down
18 changes: 11 additions & 7 deletions lib/live_toast.ex
Original file line number Diff line number Diff line change
Expand Up @@ -152,20 +152,22 @@ defmodule LiveToast do
]
end

attr(:flash, :map, required: true, doc: "the map of flash messages")
attr(:id, :string, default: "toast-group", doc: "the optional id of flash container")
attr(:connected, :boolean, default: false, doc: "whether we're in a liveview or not")
attr :flash, :map, required: true, doc: "the map of flash messages"
attr :id, :string, default: "toast-group", doc: "the optional id of flash container"
attr :connected, :boolean, default: false, doc: "whether we're in a liveview or not"

attr(:corner, :atom,
attr :corner, :atom,
values: [:top_left, :top_right, :bottom_left, :bottom_right],
default: :bottom_right,
doc: "the corner to display the toasts"
)

attr(:toast_class_fn, :any,
attr :toast_class_fn, :any,
default: &__MODULE__.toast_class_fn/1,
doc: "function to override the look of the toasts"
)

attr :class, :any,
default: "fixed z-50 max-h-screen w-full p-4 md:max-w-[420px] pointer-events-none grid origin-center",
doc: "classes for the toast group"

@doc """
Renders a group of toasts and flashes.
Expand All @@ -179,13 +181,15 @@ defmodule LiveToast do
id={@id}
module={LiveToast.LiveComponent}
corner={@corner}
class={@class}
toast_class_fn={@toast_class_fn}
f={@flash}
/>
<Components.flash_group
:if={!@connected}
id={@id}
corner={@corner}
class={@class}
toast_class_fn={@toast_class_fn}
flash={@flash}
/>
Expand Down
82 changes: 34 additions & 48 deletions lib/live_toast/components.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,28 @@ defmodule LiveToast.Components do
alias LiveToast.Utility
alias Phoenix.LiveView.JS

attr(:id, :string, doc: "the optional id of flash container")
attr(:flash, :map, default: %{}, doc: "the map of flash messages to display")
attr(:title, :string, default: nil)
attr(:kind, :atom, values: [:info, :error], doc: "used for styling and flash lookup")
attr(:rest, :global, doc: "the arbitrary HTML attributes to add to the flash container")
attr(:target, :any, default: nil, doc: "the target for the phx-click event")

attr(:duration, :integer,
attr :id, :string, doc: "the optional id of flash container"
attr :flash, :map, default: %{}, doc: "the map of flash messages to display"
attr :title, :string, default: nil
attr :kind, :atom, values: [:info, :error], doc: "used for styling and flash lookup"
attr :rest, :global, doc: "the arbitrary HTML attributes to add to the flash container"
attr :target, :any, default: nil, doc: "the target for the phx-click event"

attr :duration, :integer,
default: 6000,
doc: "the time in milliseconds before the message is automatically dismissed"
)

attr(:class_fn, :any,
attr :class_fn, :any,
required: true,
doc: "function to override the look of the toasts"
)

attr(:corner, :atom, required: true, doc: "the corner to display the toasts")
attr :corner, :atom, required: true, doc: "the corner to display the toasts"

attr(:icon, :any, default: nil, doc: "the optional icon to render in the flash message")
attr(:action, :any, default: nil, doc: "the optional action to render in the flash message")
attr(:component, :any, default: nil, doc: "the optional component to render the flash message")
attr :icon, :any, default: nil, doc: "the optional icon to render in the flash message"
attr :action, :any, default: nil, doc: "the optional action to render in the flash message"
attr :component, :any, default: nil, doc: "the optional component to render the flash message"

slot(:inner_block, doc: "the optional inner block that renders the flash message")
slot :inner_block, doc: "the optional inner block that renders the flash message"

@doc """
Default toast function. Based on the look and feel of [Sonner](https://sonner.emilkowal.ski/).
Expand Down Expand Up @@ -106,18 +104,16 @@ defmodule LiveToast.Components do
"""
end

attr(:f, :map, required: true, doc: "the map of flash messages")
attr :f, :map, required: true, doc: "the map of flash messages"

attr(:corner, :atom,
attr :corner, :atom,
values: [:top_left, :top_right, :bottom_left, :bottom_right],
default: :bottom_right,
doc: "the corner to display the toasts"
)

attr(:toast_class_fn, :any,
attr :toast_class_fn, :any,
default: &LiveToast.toast_class_fn/1,
doc: "function to override the look of the toasts"
)

@doc false
def flashes(assigns) do
Expand Down Expand Up @@ -173,46 +169,36 @@ defmodule LiveToast.Components do
"""
end

attr(:flash, :map, required: true, doc: "the map of flash messages")
attr(:id, :string, default: "toast-group", doc: "the optional id of flash container")
attr :flash, :map, required: true, doc: "the map of flash messages"
attr :id, :string, default: "toast-group", doc: "the optional id of flash container"

attr(:corner, :atom,
attr :corner, :atom,
values: [:top_left, :top_right, :bottom_left, :bottom_right],
default: :bottom_right,
doc: "the corner to display the toasts"
)

attr(:toast_class_fn, :any,
attr :toast_class_fn, :any,
default: &LiveToast.toast_class_fn/1,
doc: "function to override the look of the toasts"
)

attr :class, :any,
default: "fixed z-50 max-h-screen w-full p-4 md:max-w-[420px] pointer-events-none grid origin-center",
doc: "classes for the toast group"

# Used to render flashes-only on regular non-LV pages.
@doc false
def flash_group(assigns) do
# todo: move this to a common implementation
default_classes =
"fixed z-50 max-h-screen w-full p-4 md:max-w-[420px] pointer-events-none grid origin-center"

class =
case assigns[:corner] do
:bottom_left ->
"#{default_classes} items-end bottom-0 left-0 flex-col-reverse sm:top-auto"

:bottom_right ->
"#{default_classes} items-end bottom-0 right-0 flex-col-reverse sm:top-auto"

:top_left ->
"#{default_classes} items-start top-0 left-0 flex-col sm:bottom-auto"

:top_right ->
"#{default_classes} items-start top-0 right-0 flex-col sm:bottom-auto"
end

assigns = assign(assigns, :class, class)
assigns =
assign(assigns, :position_class, Utility.group_toast_class(assigns[:corner]))

~H"""
<div id={assigns[:id] || "flash-group"} class={@class}>
<div
id={assigns[:id] || "flash-group"}
class={[
@position_class,
@class
]}
>
<.flashes f={@flash} corner={@corner} toast_class_fn={@toast_class_fn} />
</div>
"""
Expand Down
23 changes: 4 additions & 19 deletions lib/live_toast/live_component.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ defmodule LiveToast.LiveComponent do
use Phoenix.LiveComponent

alias LiveToast.Components
alias LiveToast.Utility

@impl Phoenix.LiveComponent
def mount(socket) do
Expand Down Expand Up @@ -36,30 +37,14 @@ defmodule LiveToast.LiveComponent do

@impl Phoenix.LiveComponent
def render(assigns) do
default_classes =
"fixed z-50 max-h-screen w-full p-4 md:max-w-[420px] pointer-events-none grid origin-center"

class =
case assigns[:corner] do
:bottom_left ->
"#{default_classes} items-end bottom-0 left-0 flex-col-reverse sm:top-auto"

:bottom_right ->
"#{default_classes} items-end bottom-0 right-0 flex-col-reverse sm:top-auto"

:top_left ->
"#{default_classes} items-start top-0 left-0 flex-col sm:bottom-auto"

:top_right ->
"#{default_classes} items-start top-0 right-0 flex-col sm:bottom-auto"
end

assigns = assign(assigns, :class, class)
assigns =
assign(assigns, :position_class, Utility.group_toast_class(assigns[:corner]))

~H"""
<div
id={assigns[:id] || "toast-group"}
class={[
@position_class,
@class
]}
>
Expand Down
20 changes: 18 additions & 2 deletions lib/live_toast/utility.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ defmodule LiveToast.Utility do

alias Phoenix.LiveView.JS

attr(:name, :string, required: true, doc: "the name of the icon")
attr(:rest, :global, doc: "other html attributes")
attr :name, :string, required: true, doc: "the name of the icon"
attr :rest, :global, doc: "other html attributes"

def svg(%{name: "hero-x-mark-solid"} = assigns) do
~H"""
Expand Down Expand Up @@ -65,4 +65,20 @@ defmodule LiveToast.Utility do
"opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"}
)
end

def group_toast_class(corner_position) do
case corner_position do
:bottom_left ->
"items-end bottom-0 left-0 flex-col-reverse sm:top-auto"

:bottom_right ->
"items-end bottom-0 right-0 flex-col-reverse sm:top-auto"

:top_left ->
"items-start top-0 left-0 flex-col sm:bottom-auto"

:top_right ->
"items-start top-0 right-0 flex-col sm:bottom-auto"
end
end
end

0 comments on commit 3f73c8c

Please sign in to comment.