I have a really simple component that places a rectangle over the corner of an image to leave a cutout. As written below it works as intended:
attr :top, :boolean, default: false
attr :bottom, :boolean, default: false
attr :left, :boolean, default: false
attr :right, :boolean, default: false
def corner_cutout(assigns) do
assigns =
assign(assigns,
rotation:
case {assigns.top, assigns.bottom, assigns.left, assigns.right} do
{true, false, true, false} -> 30
{true, false, false, true} -> 330
{false, true, true, false} -> 30
{false, true, false, true} -> 330
end
)
~H"""
<div class={"w-32 h-32 bg-white transform rotate-[#{@rotation}deg]"}></div>
"""
end
and this allows me to really cleanly use the cutout in another component:
~H"""
<.corner_cutout top left />
"""
What bugs me though is the case statement, where it’s quite hard to read what is matching for each of the case clauses since it’s relying on positional arguments.
I tried re-writing by passing in assigns
to the case
statement so that it would match on something like {assigns.top, assigns.left} -> 30
and multiple variations of this, but always get the error cannot invoke remote function assigns.top/0 inside a match
.
Is there a way to re-write this so it’s more readable and I don’t have to match the position of the booleans to know what’s matching?