diff --git a/.tool-versions b/.tool-versions index 20c73bf..f816087 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,3 +1,3 @@ -elixir 1.17.3-otp-27 -erlang 27.1.2 +elixir 1.18.1-otp-27 +erlang 27.2 nodejs 20.18.0 diff --git a/README.md b/README.md index de91695..e891c6b 100644 --- a/README.md +++ b/README.md @@ -132,7 +132,7 @@ List of available components. - [Stack](https://daisyui.com/components/stack) ❌ - [Stat](https://daisyui.com/components/stat) ✅ - [Steps](https://daisyui.com/components/steps) ❌ -- [Swap](https://daisyui.com/components/swap) ❌ +- [Swap](https://daisyui.com/components/swap) ✅ - [Tabs](https://daisyui.com/components/tab) ❌ - [Table](https://daisyui.com/components/table) ✅ - [Textarea](https://daisyui.com/components/textarea) ✅ diff --git a/daisy_ui_components_site/storybook/components/swap.story.exs b/daisy_ui_components_site/storybook/components/swap.story.exs new file mode 100644 index 0000000..0e28172 --- /dev/null +++ b/daisy_ui_components_site/storybook/components/swap.story.exs @@ -0,0 +1,79 @@ +defmodule Storybook.Components.Swap do + use PhoenixStorybook.Story, :component + + alias DaisyUIComponents.Utils + + def function, do: &DaisyUIComponents.Swap.swap/1 + + def imports, do: [] + + def variations do + [ + %Variation{ + id: :swap_text, + slots: [ + """ + <:swap_on name="ON" /> + """, + """ + <:swap_off name="OFF" /> + """ + ] + }, + %Variation{ + id: :swap_icon, + slots: [ + """ + <:swap_on type="icon" name="hero-speaker-wave" /> + """, + """ + <:swap_off type="icon" name="hero-speaker-x-mark" /> + """ + ] + }, + %Variation{ + id: :swap_icon_with_rotate_effect, + attributes: %{ + animation: "rotate" + }, + slots: [ + """ + <:swap_on type="icon" name="hero-sun" /> + """, + """ + <:swap_off type="icon" name="hero-moon" /> + """ + ] + }, + %Variation{ + id: :swap_icon_with_flip_effect, + attributes: %{ + animation: "flip" + }, + slots: [ + """ + <:swap_on name="😈" /> + """, + """ + <:swap_off name="😇" /> + """ + ] + }, + %Variation{ + id: :hamburger_button, + attributes: %{ + animation: "rotate" + }, + slots: [ + """ + <:swap_on type="icon" name="hero-x-mark" /> + + """, + """ + <:swap_off type="icon" name="hero-bars-3" /> + """ + ] + }, + ] + end +end diff --git a/lib/daisy_ui_components.ex b/lib/daisy_ui_components.ex index e0deb75..7a19a3f 100644 --- a/lib/daisy_ui_components.ex +++ b/lib/daisy_ui_components.ex @@ -28,6 +28,7 @@ defmodule DaisyUIComponents do import DaisyUIComponents.Range import DaisyUIComponents.Select import DaisyUIComponents.Stat + import DaisyUIComponents.Swap import DaisyUIComponents.Table import DaisyUIComponents.TextInput import DaisyUIComponents.Textarea diff --git a/lib/daisy_ui_components/swap.ex b/lib/daisy_ui_components/swap.ex new file mode 100644 index 0000000..9ae1950 --- /dev/null +++ b/lib/daisy_ui_components/swap.ex @@ -0,0 +1,79 @@ +defmodule DaisyUIComponents.Swap do + @moduledoc """ + Select component + + https://daisyui.com/components/swap + """ + + use DaisyUIComponents.Component + + import DaisyUIComponents.Icon + + attr :class, :any, default: nil + attr :animation, :string, values: ["flip", "rotate"] + attr :rest, :global + + slot :swap_on, + doc: + "the child element that should be visible when checkbox is checked or when swap is active" do + attr :type, :string, values: ["label", "icon"] + attr :name, :string, required: true + end + + slot :swap_off, + doc: + "The child element that should be visible when checkbox is not checked or when swap is not active" do + attr :type, :string, values: ["label", "icon"] + attr :name, :string, required: true + end + + def swap(assigns) do + assigns = + assigns + |> assign_new(:animation_class, fn -> animation(assigns[:animation]) end) + + ~H""" + + """ + end + + attr :class, :any, default: nil + attr :mode, :string, required: true, values: ["on", "off"] + attr :name, :string, required: true + attr :type, :string, values: ["label", "icon"], default: "label" + + def swap_mode(assigns) do + assigns = + assigns + |> assign_new(:mode_class, fn -> mode(assigns[:mode]) end) + + ~H""" +
{@name}
+ <.icon :if={@type == "icon"} name={@name} class={classes([@mode_class, @class])} /> + """ + end + + # Animation + defp animation("flip"), do: "swap-flip" + defp animation("rotate"), do: "swap-rotate" + defp animation(_animation), do: nil + + # Mode + defp mode("on"), do: "swap-on" + defp mode("off"), do: "swap-off" + defp mode(_mode), do: nil +end diff --git a/mix.exs b/mix.exs index 04d36d9..d0932c9 100644 --- a/mix.exs +++ b/mix.exs @@ -2,7 +2,7 @@ defmodule DaisyUIComponents.MixProject do use Mix.Project @source_url "https://github.com/phcurado/daisy_ui_components" - @version "0.2.0" + @version "0.2.1" def project do [ @@ -67,12 +67,13 @@ defmodule DaisyUIComponents.MixProject do DaisyUIComponents.Alert, DaisyUIComponents.Avatar, DaisyUIComponents.Badge, - DaisyUIComponents.ButtonGroup, + DaisyUIComponents.Breadcrumbs, DaisyUIComponents.Button, + DaisyUIComponents.ButtonGroup, DaisyUIComponents.Card, DaisyUIComponents.Checkbox, - DaisyUIComponents.CoreComponents, DaisyUIComponents.Drawer, + DaisyUIComponents.Dropdown, DaisyUIComponents.Form, DaisyUIComponents.Icon, DaisyUIComponents.Input, @@ -80,11 +81,14 @@ defmodule DaisyUIComponents.MixProject do DaisyUIComponents.Modal, DaisyUIComponents.Navbar, DaisyUIComponents.Pagination, + DaisyUIComponents.Range, DaisyUIComponents.Select, DaisyUIComponents.Stat, + DaisyUIComponents.Swap, DaisyUIComponents.Table, DaisyUIComponents.TextInput, DaisyUIComponents.Textarea, + DaisyUIComponents.Toggle, DaisyUIComponents.Tooltip, DaisyUIComponents.Loading ] diff --git a/test/daisy_ui_components/swap_test.exs b/test/daisy_ui_components/swap_test.exs new file mode 100644 index 0000000..b637814 --- /dev/null +++ b/test/daisy_ui_components/swap_test.exs @@ -0,0 +1,61 @@ +defmodule DaisyUIComponents.SwapTest do + use ExUnit.Case + + import Phoenix.Component + import Phoenix.LiveViewTest + import DaisyUIComponents.Swap + + test "swap" do + assigns = %{} + + swap = + rendered_to_string(~H""" + <.swap /> + """) + + assert swap =~ ~s( + """) =~ ~s(