Ok, I’ve tried to do this with hooks, but I have some very weird behaviour:
Hooks.Highlight = {
updated() {
if (this.handler) {
clearTimeout(this.handler);
}
if (this.el.dataset.highlight === "on") {
const handler = setTimeout(() => {
this.el.setAttribute("data-highlight", "off");
}, 1000);
this.handler = handler;
}
}
}
attr(:id, :any, required: true)
attr(:trigger, :any)
attr(:duration, :integer)
slot(:inner_block)
attr(:rest, :global)
def highlight(assigns) do
assigns =
assign_new(assigns, :highlight, fn ->
if changed?(assigns, :trigger) do
"on"
else
"off"
end
end)
~H"""
<div id={@id} data-id={@id} phx-hook="Highlight" {@rest} data-highlight={@highlight}>
<%= render_slot(@inner_block) %>
</div>
"""
end
defmodule Storybook.CoreComponents.Highlight do
use PhoenixStorybook.Story, :example
import Elixir.DomainModellingWeb.CoreComponents
@impl true
def mount(_params, _session, socket) do
{:ok, assign(socket, value: 10, value2: 20, value3: 30)}
end
@impl true
def render(assigns) do
~H"""
<.highlight
id="1"
trigger={@value}
duration={500}
class="data-[highlight=on]:bg-primary-500 bg-neutral-900 text-white"
>
<div class="p-4">
<button phx-click="click">Value 1: <%= @value %></button>
</div>
</.highlight>
<.highlight
id="2"
trigger={@value2}
duration={500}
class="data-[highlight=on]:bg-primary-500 bg-neutral-900 text-white"
>
<div class="p-4">
<button phx-click="click2">Value 2: <%= @value2 %></button>
</div>
</.highlight>
<.highlight
id="3"
trigger={@value3}
duration={500}
class="data-[highlight=on]:bg-primary-500 bg-neutral-900 text-white"
>
<div class="p-4">
<button phx-click="click3">Value 3: <%= @value3 %></button>
</div>
</.highlight>
"""
end
@impl true
def handle_event("click", _, socket) do
{:noreply,
socket
|> update(:value, fn value ->
value + 1
end)}
end
@impl true
def handle_event("click2", _, socket) do
{:noreply,
socket
|> update(:value2, fn value ->
value + 1
end)}
end
@impl true
def handle_event("click3", _, socket) do
{:noreply,
socket
|> update(:value3, fn value ->
value + 1
end)}
|> dbg
end
end
The strange behaviour I get: every time I click, all previous highlight components that have been clicked also run the updated hook.
The items that haven’t been previously updated, don’t get in the updated hook.
What’s even stranger is that for these items that get in the update hook, the data-highlight changes to “on”.
On the elixir side, nothing happens in the def highlight though.
Here you can see the behaviour: https://drive.google.com/file/d/1yjIPwj4OXkdojtFQLXbVnJG1I9IBtWGD/view?usp=drive_link
That seems like a bug, but I guess there’s a bigger change that I’m doing something wrong.