Skip to content

Commit

Permalink
add swap component
Browse files Browse the repository at this point in the history
  • Loading branch information
phcurado committed Jan 18, 2025
1 parent 310c5a2 commit 616485d
Show file tree
Hide file tree
Showing 7 changed files with 230 additions and 6 deletions.
4 changes: 2 additions & 2 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
79 changes: 79 additions & 0 deletions daisy_ui_components_site/storybook/components/swap.story.exs
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions lib/daisy_ui_components.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
79 changes: 79 additions & 0 deletions lib/daisy_ui_components/swap.ex
Original file line number Diff line number Diff line change
@@ -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"""
<label class={classes(["swap", @animation_class, @class])} {@rest}>
<input class="hidden" type="checkbox" />
<.swap_mode
:for={swap_on <- @swap_on}
type={Map.get(swap_on, :type, "label")}
name={swap_on.name}
mode="on"
/>
<.swap_mode
:for={swap_off <- @swap_off}
type={Map.get(swap_off, :type, "label")}
name={swap_off.name}
mode="off"
/>
</label>
"""
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"""
<div :if={@type == "label"} class={classes([@mode_class, @class])}>{@name}</div>
<.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
10 changes: 7 additions & 3 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -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
[
Expand Down Expand Up @@ -67,24 +67,28 @@ 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,
DaisyUIComponents.Join,
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
]
Expand Down
61 changes: 61 additions & 0 deletions test/daisy_ui_components/swap_test.exs
Original file line number Diff line number Diff line change
@@ -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(<label)
assert swap =~ ~s(class="swap")
end

test "swap animations" do
for animation <- ["flip", "rotate"] do
assigns = %{animation: animation}

assert rendered_to_string(~H"""
<.swap animation={@animation} />
""") =~ ~s(<label class="swap swap-#{animation}">)
end
end

test "swap label slots" do
assigns = %{}

swap =
rendered_to_string(~H"""
<.swap animation="flip">
<:swap_on name="ON" />
<:swap_off name="OFF" />
</.swap>
""")

assert swap =~ ~s(<label class="swap swap-flip")
assert swap =~ ~s(<div class="swap-on">ON)
assert swap =~ ~s(<div class="swap-off">OFF)
end

test "swap icon slots" do
assigns = %{}

swap =
rendered_to_string(~H"""
<.swap animation="flip">
<:swap_on type="icon" name="hero-plus" />
<:swap_off type="icon" name="hero-minus" />
</.swap>
""")

assert swap =~ ~s(<label class="swap swap-flip")
assert swap =~ ~s(<span class="hero-plus swap-on">)
assert swap =~ ~s(<span class="hero-minus swap-off">)
end
end

0 comments on commit 616485d

Please sign in to comment.