Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for grid output max height #2846

Merged
merged 1 commit into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/livebook/runtime.ex
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ defprotocol Livebook.Runtime do
outputs: list(t()),
columns: pos_integer() | tuple(),
gap: non_neg_integer(),
max_height: pos_integer() | nil,
boxed: boolean()
}

Expand Down
26 changes: 16 additions & 10 deletions lib/livebook/session.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3100,16 +3100,21 @@ defmodule Livebook.Session do

# Traverse composite outputs

# defp normalize_runtime_output(output) when output.type in [:frame, :tabs, :grid] do
# outputs = Enum.map(output.outputs, &normalize_runtime_output/1)
# %{output | outputs: outputs}
# end
defp normalize_runtime_output(%{type: :grid} = grid) do
grid
|> Map.update!(:outputs, fn outputs -> Enum.map(outputs, &normalize_runtime_output/1) end)
|> Map.put_new(:max_height, nil)
end

defp normalize_runtime_output(%{type: type} = output) when type in [:frame, :tabs] do
Map.update!(output, :outputs, fn outputs -> Enum.map(outputs, &normalize_runtime_output/1) end)
end

# defp normalize_runtime_output(%{type: :frame_update} = output) do
# {update_type, new_outputs} = output.update
# new_outputs = Enum.map(new_outputs, &normalize_runtime_output/1)
# %{output | update: {update_type, new_outputs}}
# end
defp normalize_runtime_output(%{type: :frame_update} = output) do
{update_type, new_outputs} = output.update
new_outputs = Enum.map(new_outputs, &normalize_runtime_output/1)
%{output | update: {update_type, new_outputs}}
end

defp normalize_runtime_output(output) when is_map(output), do: output

Expand Down Expand Up @@ -3191,7 +3196,8 @@ defmodule Livebook.Session do
outputs: Enum.map(outputs, &normalize_runtime_output/1),
columns: Map.get(info, :columns, 1),
gap: Map.get(info, :gap, 8),
boxed: Map.get(info, :boxed, false)
boxed: Map.get(info, :boxed, false),
max_height: Map.get(info, :max_height)
}
|> normalize_runtime_output()
end
Expand Down
2 changes: 2 additions & 0 deletions lib/livebook_web/live/output.ex
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ defmodule LivebookWeb.Output do
id: id,
columns: grid.columns,
gap: grid.gap,
max_height: grid.max_height,
outputs: grid.outputs,
session_id: session_id,
session_pid: session_pid,
Expand All @@ -189,6 +190,7 @@ defmodule LivebookWeb.Output do
outputs={@outputs}
columns={@columns}
gap={@gap}
max_height={@max_height}
session_id={@session_id}
session_pid={@session_pid}
input_views={@input_views}
Expand Down
40 changes: 32 additions & 8 deletions lib/livebook_web/live/output/grid_component.ex
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,16 @@ defmodule LivebookWeb.Output.GridComponent do
@impl true
def render(assigns) do
~H"""
<div id={@id} class="overflow-auto tiny-scrollbar">
<div
id={@id}
phx-hook="ScrollOnUpdate"
class="overflow-auto tiny-scrollbar pr-1.5 -mr-1.5"
style={max_height_style(@max_height)}
>
<div
id={"#{@id}-grid"}
class="grid grid-cols-2 w-full"
style={"grid-template-columns: #{make_template(@columns)}; gap: #{@gap}px"}
style={join_styles([columns_style(@columns), gap_style(@gap)])}
phx-update="stream"
>
<div :for={{dom_id, output} <- @streams.outputs} id={dom_id}>
Expand All @@ -49,17 +54,36 @@ defmodule LivebookWeb.Output.GridComponent do
"""
end

defp make_template(columns) when is_tuple(columns) do
defp columns_style(columns) when is_tuple(columns) do
columns = Tuple.to_list(columns)

if Enum.all?(columns, &is_integer/1) do
Enum.map_join(columns, " ", fn n -> "minmax(0, #{n}fr)" end)
else
""
template = Enum.map_join(columns, " ", fn n -> "minmax(0, #{n}fr)" end)
"grid-template-columns: #{template}"
end
end

defp make_template(columns) when is_integer(columns), do: "repeat(#{columns}, minmax(0, 1fr))"
defp columns_style(columns) when is_integer(columns) do
"grid-template-columns: repeat(#{columns}, minmax(0, 1fr))"
end

defp columns_style(_columns), do: nil

defp gap_style(gap) when is_integer(gap) do
"#{gap}px"
end

defp gap_style(_other), do: nil

defp make_template(_columns), do: ""
defp max_height_style(max_height) when is_integer(max_height) do
"max-height: #{max_height}px"
end

defp max_height_style(_other), do: nil

defp join_styles(styles) do
styles
|> Enum.reject(&is_nil/1)
|> Enum.join("; ")
end
end