Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add hability to customize group toast classes #8

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading