Redesign cell indicators to include language (#2862)

This commit is contained in:
Jonatan Kłosko 2024-11-19 15:29:44 +01:00 committed by GitHub
parent 156b21d06a
commit 3b0f9cecd7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 122 additions and 45 deletions

View file

@ -23,7 +23,7 @@ Example usage:
}
.tooltip.distant-medium {
--distance: 10px;
--distance: 14px;
}
/* Tooltip text */

View file

@ -5,14 +5,34 @@
background-color: #282c34;
}
body[data-editor-theme="light"] .bg-editor {
background-color: #fafafa;
.bg-editor-lighter {
background-color: #2f343e;
}
.border-editor {
border-color: #363c46;
}
.text-editor {
color: #c4cad6;
}
body[data-editor-theme="light"] .bg-editor {
background-color: #fafafa;
}
body[data-editor-theme="light"] .bg-editor-lighter {
background-color: #ebebec;
}
body[data-editor-theme="light"] .border-editor {
border-color: #dfdfe0;
}
body[data-editor-theme="light"] .text-editor {
color: #383a41;
}
.font-editor {
font-family: "JetBrains Mono", "Droid Sans Mono", "monospace";
font-variant-ligatures: none;

View file

@ -21,6 +21,12 @@ function buildEditorTheme(colors, { dark }) {
borderRadius: "8px",
fontSize: "14px",
fontFamily: fonts.mono,
// A workaround for a strange contenteditable behaviour in
// Chrome and Safari, where clicking on the right side of the
// editor results in focus. See https://discuss.codemirror.net/t/editor-focus-happens-when-clicking-outside-the-editor/7544/3
display: "inline-flex !important",
width: "100%",
},
"&.cm-focused": {

View file

@ -641,7 +641,7 @@ defmodule LivebookWeb.CoreComponents do
def status_indicator(assigns) do
~H"""
<span class="relative flex h-3 w-3">
<span class="relative flex h-2.5 w-2.5">
<span
:if={animated_status_circle_class(@variant)}
class={[
@ -650,7 +650,7 @@ defmodule LivebookWeb.CoreComponents do
]}
>
</span>
<span class={[status_circle_class(@variant), "relative inline-flex rounded-full h-3 w-3"]}>
<span class={[status_circle_class(@variant), "relative inline-flex rounded-full h-2.5 w-2.5"]}>
</span>
</span>
"""

View file

@ -46,46 +46,24 @@ defmodule LivebookWeb.NotebookComponents do
def cell_icon(%{cell_type: :code, language: :elixir} = assigns) do
~H"""
<div class="flex w-6 h-6 bg-purple-100 rounded items-center justify-center">
<svg width="11" height="15" viewBox="0 0 11 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M5.7784 3.58083C7.4569 5.87527 9.67878 5.70652 10.0618 9.04833C10.1147 12.9425 8.03684
14.27 6.55353 14.6441C4.02227 15.3635 1.7644 14.2813 0.875648 11.8316C-0.83154 7.89408 2.36684
1.41746 4.42502 0.0668945C4.60193 1.32119 5.05745 2.51995 5.75815 3.57521L5.7784 3.58083Z"
fill="#663299"
/>
</svg>
<div class="w-6 h-6 p-1 rounded flex items-center justify-center bg-purple-100">
<.language_icon language={:elixir} class="w-full h-full text-[#663299]" />
</div>
"""
end
def cell_icon(%{cell_type: :code, language: :erlang} = assigns) do
~H"""
<div class="flex w-6 h-6 bg-red-100 rounded items-center justify-center">
<svg width="18" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15 10">
<g fill="#a90533">
<path d="M2.4 10A7.7 7.7 0 0 1 .5 4.8c0-2 .6-3.6 1.6-4.8H0v10ZM13 10c.5-.6 1-1.2 1.4-2l-2.3-1.2c-.8 1.4-2 2.6-3.6 2.6-2.3 0-3.2-2-3.2-4.8H14V4c0-1.6-.3-3-1-4H15v10h-2Zm0 0" />
<path d="M5.5 2.3c.1-1.2 1-2 2.1-2s1.9.8 2 2Zm0 0" />
</g>
</svg>
<div class="w-6 h-6 p-1 rounded flex items-center justify-center bg-red-100">
<.language_icon language={:erlang} class="w-full h-full text-[#a90533]" />
</div>
"""
end
def cell_icon(%{cell_type: :markdown} = assigns) do
~H"""
<div class="flex w-6 h-6 bg-blue-100 rounded items-center justify-center">
<svg width="16" height="14" viewBox="0 0 16 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M1.25 0.25H14.75C14.9489 0.25 15.1397 0.329018 15.2803 0.46967C15.421 0.610322 15.5 0.801088
15.5 1V13C15.5 13.1989 15.421 13.3897 15.2803 13.5303C15.1397 13.671 14.9489 13.75 14.75 13.75H1.25C1.05109
13.75 0.860322 13.671 0.71967 13.5303C0.579018 13.3897 0.5 13.1989 0.5 13V1C0.5 0.801088 0.579018 0.610322
0.71967 0.46967C0.860322 0.329018 1.05109 0.25 1.25 0.25ZM4.25 9.625V6.625L5.75 8.125L7.25
6.625V9.625H8.75V4.375H7.25L5.75 5.875L4.25 4.375H2.75V9.625H4.25ZM12.5 7.375V4.375H11V7.375H9.5L11.75
9.625L14 7.375H12.5Z"
fill="#3E64FF"
/>
</svg>
<div class="w-6 h-6 p-1 rounded flex items-center justify-center bg-blue-100">
<.language_icon language={:markdown} class="w-full h-full text-[#3e64ff]" />
</div>
"""
end
@ -97,4 +75,51 @@ defmodule LivebookWeb.NotebookComponents do
</div>
"""
end
@doc """
Renders an icon for the given language.
"""
attr :language, :atom, required: true
attr :class, :string, default: nil
def language_icon(%{language: :elixir} = assigns) do
~H"""
<svg class={@class} viewBox="0 0 11 15" xmlns="http://www.w3.org/2000/svg">
<path
d="M5.7784 3.58083C7.4569 5.87527 9.67878 5.70652 10.0618 9.04833C10.1147 12.9425 8.03684
14.27 6.55353 14.6441C4.02227 15.3635 1.7644 14.2813 0.875648 11.8316C-0.83154 7.89408 2.36684
1.41746 4.42502 0.0668945C4.60193 1.32119 5.05745 2.51995 5.75815 3.57521L5.7784 3.58083Z"
fill="currentColor"
>
</path>
</svg>
"""
end
def language_icon(%{language: :erlang} = assigns) do
~H"""
<svg class={@class} viewBox="0 0 15 10" xmlns="http://www.w3.org/2000/svg">
<g fill="currentColor">
<path d="M2.4 10A7.7 7.7 0 0 1 .5 4.8c0-2 .6-3.6 1.6-4.8H0v10ZM13 10c.5-.6 1-1.2 1.4-2l-2.3-1.2c-.8 1.4-2 2.6-3.6 2.6-2.3 0-3.2-2-3.2-4.8H14V4c0-1.6-.3-3-1-4H15v10h-2Zm0 0" />
<path d="M5.5 2.3c.1-1.2 1-2 2.1-2s1.9.8 2 2Zm0 0" />
</g>
</svg>
"""
end
def language_icon(%{language: :markdown} = assigns) do
~H"""
<svg class={@class} viewBox="0 0 16 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M1.25 0.25H14.75C14.9489 0.25 15.1397 0.329018 15.2803 0.46967C15.421 0.610322 15.5 0.801088
15.5 1V13C15.5 13.1989 15.421 13.3897 15.2803 13.5303C15.1397 13.671 14.9489 13.75 14.75 13.75H1.25C1.05109
13.75 0.860322 13.671 0.71967 13.5303C0.579018 13.3897 0.5 13.1989 0.5 13V1C0.5 0.801088 0.579018 0.610322
0.71967 0.46967C0.860322 0.329018 1.05109 0.25 1.25 0.25ZM4.25 9.625V6.625L5.75 8.125L7.25
6.625V9.625H8.75V4.375H7.25L5.75 5.875L4.25 4.375H2.75V9.625H4.25ZM12.5 7.375V4.375H11V7.375H9.5L11.75
9.625L14 7.375H12.5Z"
fill="currentColor"
/>
</svg>
"""
end
end

View file

@ -100,9 +100,6 @@ defmodule LivebookWeb.SessionLive.CellComponent do
/>
</:primary>
<:secondary>
<div :if={@cell_view.language == :erlang} class="grayscale">
<.cell_icon cell_type={:code} language={:erlang} />
</div>
<.cell_settings_button cell_id={@cell_view.id} session_id={@session_id} />
<.amplify_output_button />
<.cell_link_button cell_id={@cell_view.id} />
@ -121,7 +118,7 @@ defmodule LivebookWeb.SessionLive.CellComponent do
intellisense
/>
<div class="absolute bottom-2 right-2">
<.cell_status id={@cell_view.id} cell_view={@cell_view} />
<.cell_indicators id={@cell_view.id} variant="editor" cell_view={@cell_view} />
</div>
</div>
<.doctest_summary cell_id={@cell_view.id} doctest_summary={@cell_view.eval.doctest_summary} />
@ -155,9 +152,9 @@ defmodule LivebookWeb.SessionLive.CellComponent do
</.cell_actions>
<.cell_body>
<div data-el-info-box>
<div class="p-3 flex items-center justify-between border border-gray-200 text-sm text-gray-400 font-medium rounded-lg">
<span>Notebook dependencies and setup</span>
<.cell_status id={"#{@cell_view.id}-1"} cell_view={@cell_view} />
<div class="p-3 flex items-center justify-between border border-gray-200 text-sm text-gray-400 rounded-lg">
<span class="font-medium">Notebook dependencies and setup</span>
<.cell_indicators id={"#{@cell_view.id}-1"} variant="default" cell_view={@cell_view} />
</div>
</div>
<div data-el-editor-box>
@ -170,7 +167,7 @@ defmodule LivebookWeb.SessionLive.CellComponent do
intellisense
/>
<div class="absolute bottom-2 right-2">
<.cell_status id={"#{@cell_view.id}-2"} cell_view={@cell_view} />
<.cell_indicators id={"#{@cell_view.id}-2"} variant="editor" cell_view={@cell_view} />
</div>
</div>
<.evaluation_outputs
@ -258,9 +255,9 @@ defmodule LivebookWeb.SessionLive.CellComponent do
<.content_skeleton empty={false} />
</div>
<% end %>
<div class="flex flex-col items-end space-y-2">
<div class="flex flex-col items-end space-y-2 text-gray-400">
<div></div>
<.cell_status id={"#{@cell_view.id}-1"} cell_view={@cell_view} />
<.cell_indicators id={"#{@cell_view.id}-1"} variant="default" cell_view={@cell_view} />
</div>
</div>
<div data-el-editor-box>
@ -274,7 +271,7 @@ defmodule LivebookWeb.SessionLive.CellComponent do
read_only
/>
<div class="absolute bottom-2 right-2">
<.cell_status id={"#{@cell_view.id}-2"} cell_view={@cell_view} />
<.cell_indicators id={"#{@cell_view.id}-2"} variant="editor" cell_view={@cell_view} />
</div>
</div>
</div>
@ -683,6 +680,35 @@ defmodule LivebookWeb.SessionLive.CellComponent do
"""
end
defp cell_indicators(assigns) do
~H"""
<div class="flex gap-1">
<div :if={has_status?(@cell_view)} class={cell_indicator_container_class(@variant)}>
<.cell_status id={@id} cell_view={@cell_view} />
</div>
<div class={cell_indicator_container_class(@variant)}>
<.language_icon language={cell_language(@cell_view)} class="w-3 h-3" />
</div>
</div>
"""
end
defp cell_indicator_container_class(variant) do
[
"px-1.5 h-[22px] rounded-lg flex items-center",
case variant do
"default" -> "bg-gray-50 border border-gray-200 text-gray-500 px-1.5 h-[22px]"
"editor" -> "bg-editor-lighter border border-editor text-editor px-1.5 h-[22px]"
end
]
end
defp cell_language(%{language: language}), do: language
defp cell_language(%{type: :smart}), do: :elixir
defp has_status?(%{eval: %{status: :ready, validity: :fresh}}), do: false
defp has_status?(_cell_view), do: true
defp cell_status(%{cell_view: %{eval: %{status: :evaluating}}} = assigns) do
~H"""
<.cell_status_indicator variant={:progressing} change_indicator={true}>
@ -753,7 +779,7 @@ defmodule LivebookWeb.SessionLive.CellComponent do
~H"""
<div class={[@tooltip && "tooltip", "bottom distant-medium"]} data-tooltip={@tooltip}>
<div class="flex items-center space-x-1">
<div class="flex text-xs text-gray-400" data-el-cell-status>
<div class="flex text-[11px]" data-el-cell-status>
<%= render_slot(@inner_block) %>
<span :if={@change_indicator} data-el-change-indicator>*</span>
</div>