Packages
livebook
0.19.5
0.19.8
0.19.7
0.19.6
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.6
0.18.5
0.18.4
0.18.3
0.18.2
0.18.1
0.18.0
0.17.3
0.17.2
0.17.1
0.17.0
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.14.0-rc.1
0.14.0-rc.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.2
0.1.1
0.1.0
Automate code & data workflows with interactive notebooks
Current section
Files
Jump to
Current section
Files
lib/livebook_web/live/output/tabs_component.ex
defmodule LivebookWeb.Output.TabsComponent do
use LivebookWeb, :live_component
@impl true
def mount(socket) do
{:ok, stream(socket, :outputs, [])}
end
@impl true
def update(assigns, socket) do
{labels, assigns} = Map.pop!(assigns, :labels)
{outputs, assigns} = Map.pop!(assigns, :outputs)
# We compute these only on initial render, when we have all outputs
socket =
socket
|> assign_new(:labels, fn ->
Enum.zip_with(labels, outputs, fn label, {output_idx, _} -> {output_idx, label} end)
end)
|> assign_new(:active_idx, fn ->
get_in(outputs, [Access.at(0), Access.elem(0)])
end)
socket = assign(socket, assigns)
stream_items =
for {idx, output} <- outputs do
id = "#{idx}-tabs-item"
%{id: id, idx: idx, output: output}
end
socket = stream(socket, :outputs, stream_items)
{:ok, socket}
end
@impl true
def render(assigns) do
~H"""
<div id={@id}>
<div class="tabs mb-2" id={"#{@id}-tabs"}>
<%!-- Note that we use > in the phx-click selectors, because there may be nested tabs --%>
<button
:for={{output_idx, label} <- @labels}
id={"#{@id}-tabs-#{output_idx}"}
class={["tab", output_idx == @active_idx && "active"]}
phx-click={
JS.remove_class("active", to: "##{@id}-tabs > .tab.active")
|> JS.add_class("active")
|> JS.add_class("hidden", to: "##{@id}-tab-contents > [data-tab-content]:not(.hidden)")
|> JS.remove_class("hidden",
to: ~s/##{@id}-tab-contents > [data-tab-content="#{output_idx}"]/
)
}
>
{label}
</button>
</div>
<div id={"#{@id}-tab-contents"} phx-update="stream">
<div
:for={{dom_id, output} <- @streams.outputs}
id={dom_id}
data-tab-content={output.idx}
class={[output.idx != @active_idx && "hidden"]}
>
<LivebookWeb.Output.output
id={"outputs-#{output.idx}"}
output={output.output}
session_id={@session_id}
session_pid={@session_pid}
input_views={@input_views}
client_id={@client_id}
cell_id={@cell_id}
/>
</div>
</div>
</div>
"""
end
end