mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-09-08 05:54:20 +08:00
Insert section (#114)
* Add section insertion button * Add shortcut for inserting section * Pass buttons to the component * Add mix alias for running both formatter * Adjustments * Make the buttons group component stateless
This commit is contained in:
parent
50db813092
commit
fe5dfe3b86
8 changed files with 77 additions and 42 deletions
|
@ -5,7 +5,7 @@
|
|||
}
|
||||
|
||||
.button:not(:disabled) {
|
||||
@apply hover:bg-gray-50 focus:bg-gray-50;
|
||||
@apply hover:bg-gray-100 focus:bg-gray-100;
|
||||
}
|
||||
|
||||
.button:disabled {
|
||||
|
@ -13,7 +13,7 @@
|
|||
}
|
||||
|
||||
.button-sm {
|
||||
@apply px-3 py-1;
|
||||
@apply px-2 py-1;
|
||||
}
|
||||
|
||||
.button-danger {
|
||||
|
|
|
@ -169,6 +169,8 @@ function handleDocumentKeyDown(hook, event) {
|
|||
insertCellBelowFocused(hook, "markdown");
|
||||
} else if (keyBuffer.tryMatch(["M"])) {
|
||||
insertCellAboveFocused(hook, "markdown");
|
||||
} else if (keyBuffer.tryMatch(["S"])) {
|
||||
addSection(hook);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -380,6 +382,10 @@ function insertCellAboveFocused(hook, type) {
|
|||
}
|
||||
}
|
||||
|
||||
function addSection(hook) {
|
||||
hook.pushEvent("add_section", {});
|
||||
}
|
||||
|
||||
function insertFirstCell(hook, type) {
|
||||
const sectionIds = getSectionIds();
|
||||
|
||||
|
|
13
lib/livebook_web/live/insert_buttons_component.ex
Normal file
13
lib/livebook_web/live/insert_buttons_component.ex
Normal file
|
@ -0,0 +1,13 @@
|
|||
defmodule LivebookWeb.InsertButtonsComponent do
|
||||
use LivebookWeb, :live_component
|
||||
|
||||
def render(assigns) do
|
||||
~L"""
|
||||
<div class="relative top-0.5 m-0 flex justify-center">
|
||||
<div class="absolute z-10 <%= if(@persistent, do: "opacity-100", else: "opacity-0") %> hover:opacity-100 focus-within:opacity-100 flex space-x-2 justify-center items-center">
|
||||
<%= render_block(@inner_block) %>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
end
|
|
@ -1,26 +0,0 @@
|
|||
defmodule LivebookWeb.InsertCellComponent do
|
||||
use LivebookWeb, :live_component
|
||||
|
||||
def render(assigns) do
|
||||
~L"""
|
||||
<div class="relative top-0.5 m-0 flex justify-center">
|
||||
<div class="absolute z-10 <%= if(@persistent, do: "opacity-100", else: "opacity-0") %> hover:opacity-100 focus-within:opacity-100 flex space-x-2 justify-center items-center">
|
||||
<button class="py-1 px-2 text-sm text-gray-600 font-medium rounded-lg border border-gray-200 bg-gray-50 hover:bg-gray-100 focus:bg-gray-100"
|
||||
phx-click="insert_cell"
|
||||
phx-value-type="markdown"
|
||||
phx-value-section_id="<%= @section_id %>"
|
||||
phx-value-index="<%= @index %>">
|
||||
+ Markdown
|
||||
</button>
|
||||
<button class="py-1 px-2 text-sm text-gray-600 font-medium rounded-lg border border-gray-200 bg-gray-50 hover:bg-gray-100 focus:bg-gray-100"
|
||||
phx-click="insert_cell"
|
||||
phx-value-type="elixir"
|
||||
phx-value-section_id="<%= @section_id %>"
|
||||
phx-value-index="<%= @index %>">
|
||||
+ Elixir
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
end
|
|
@ -26,22 +26,46 @@ defmodule LivebookWeb.SectionComponent do
|
|||
</div>
|
||||
<div class="container py-2">
|
||||
<div class="flex flex-col space-y-1">
|
||||
<%= live_component @socket, LivebookWeb.InsertCellComponent,
|
||||
id: "#{@section.id}:0",
|
||||
section_id: @section.id,
|
||||
index: 0,
|
||||
persistent: @section.cells == [] %>
|
||||
<%= for {cell, index} <- Enum.with_index(@section.cells) do %>
|
||||
<%= live_component @socket, LivebookWeb.InsertButtonsComponent,
|
||||
persistent: false do %>
|
||||
<button class="button button-sm"
|
||||
phx-click="insert_cell"
|
||||
phx-value-type="markdown"
|
||||
phx-value-section_id="<%= @section.id %>"
|
||||
phx-value-index="<%= index %>"
|
||||
>+ Markdown</button>
|
||||
<button class="button button-sm"
|
||||
phx-click="insert_cell"
|
||||
phx-value-type="elixir"
|
||||
phx-value-section_id="<%= @section.id %>"
|
||||
phx-value-index="<%= index %>"
|
||||
>+ Elixir</button>
|
||||
<% end %>
|
||||
<%= live_component @socket, LivebookWeb.CellComponent,
|
||||
id: cell.id,
|
||||
session_id: @session_id,
|
||||
cell: cell,
|
||||
cell_info: @cell_infos[cell.id] %>
|
||||
<%= live_component @socket, LivebookWeb.InsertCellComponent,
|
||||
id: "#{@section.id}:#{index + 1}",
|
||||
section_id: @section.id,
|
||||
index: index + 1,
|
||||
persistent: false %>
|
||||
<% end %>
|
||||
<%= live_component @socket, LivebookWeb.InsertButtonsComponent,
|
||||
persistent: @section.cells == [] do %>
|
||||
<button class="button button-sm"
|
||||
phx-click="insert_cell"
|
||||
phx-value-type="markdown"
|
||||
phx-value-section_id="<%= @section.id %>"
|
||||
phx-value-index="<%= length(@section.cells) %>"
|
||||
>+ Markdown</button>
|
||||
<button class="button button-sm"
|
||||
phx-click="insert_cell"
|
||||
phx-value-type="elixir"
|
||||
phx-value-section_id="<%= @section.id %>"
|
||||
phx-value-index="<%= length(@section.cells) %>"
|
||||
>+ Elixir</button>
|
||||
<button class="button button-sm"
|
||||
phx-click="insert_section"
|
||||
phx-value-index="<%= @index + 1 %>"
|
||||
>+ Section</button>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -83,14 +83,14 @@ defmodule LivebookWeb.SessionLive do
|
|||
</span>
|
||||
<span class="tooltip right distant" aria-label="Notebook settings (sn)">
|
||||
<%= live_patch to: Routes.session_path(@socket, :settings, @session_id, "file"),
|
||||
class: "text-gray-600 hover:text-gray-50 focus:text-gray-50 #{if(@live_action == :settings, do: "text-gray-50")}" do %>
|
||||
class: "text-gray-600 hover:text-gray-50 focus:text-gray-50 #{if(@live_action == :settings, do: "text-gray-50")}" do %>
|
||||
<%= remix_icon("settings-4-fill", class: "text-2xl") %>
|
||||
<% end %>
|
||||
</span>
|
||||
<div class="flex-grow"></div>
|
||||
<span class="tooltip right distant" aria-label="Keyboard shortcuts (?)">
|
||||
<%= live_patch to: Routes.session_path(@socket, :shortcuts, @session_id),
|
||||
class: "text-gray-600 hover:text-gray-50 focus:text-gray-50 #{if(@live_action == :shortcuts, do: "text-gray-50")}" do %>
|
||||
class: "text-gray-600 hover:text-gray-50 focus:text-gray-50 #{if(@live_action == :shortcuts, do: "text-gray-50")}" do %>
|
||||
<%= remix_icon("keyboard-box-fill", class: "text-2xl") %>
|
||||
<% end %>
|
||||
</span>
|
||||
|
@ -125,9 +125,18 @@ defmodule LivebookWeb.SessionLive do
|
|||
data-update-attribute="phx-value-name"><%= @data.notebook.name %></h1>
|
||||
</div>
|
||||
<div class="flex flex-col w-full space-y-16">
|
||||
<%= for section <- @data.notebook.sections do %>
|
||||
<%= if @data.notebook.sections == [] do %>
|
||||
<div class="flex justify-center">
|
||||
<button class="button button-sm"
|
||||
phx-click="insert_section"
|
||||
phx-value-index="0"
|
||||
>+ Section</button>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= for {section, index} <- Enum.with_index(@data.notebook.sections) do %>
|
||||
<%= live_component @socket, LivebookWeb.SectionComponent,
|
||||
id: section.id,
|
||||
index: index,
|
||||
session_id: @session_id,
|
||||
section: section,
|
||||
cell_infos: @data.cell_infos %>
|
||||
|
@ -183,6 +192,13 @@ defmodule LivebookWeb.SessionLive do
|
|||
{:noreply, socket}
|
||||
end
|
||||
|
||||
def handle_event("insert_section", %{"index" => index}, socket) do
|
||||
index = ensure_integer(index) |> max(0)
|
||||
Session.insert_section(socket.assigns.session_id, index)
|
||||
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
||||
def handle_event("delete_section", %{"section_id" => section_id}, socket) do
|
||||
Session.delete_section(socket.assigns.session_id, section_id)
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ defmodule LivebookWeb.SessionLive.ShortcutsComponent do
|
|||
%{seq: ["N"], desc: "Insert Elixir cell above"},
|
||||
%{seq: ["M"], desc: "Insert Markdown cell above"},
|
||||
%{seq: ["dd"], desc: "Delete cell"},
|
||||
%{seq: ["S"], desc: "Add section"},
|
||||
%{seq: ["ee"], desc: "Evaluate cell"},
|
||||
%{seq: ["es"], desc: "Evaluate section"},
|
||||
%{seq: ["ea"], desc: "Evaluate all stale/new cells"},
|
||||
|
|
3
mix.exs
3
mix.exs
|
@ -59,7 +59,8 @@ defmodule Livebook.MixProject do
|
|||
setup: ["deps.get", "cmd npm install --prefix assets"],
|
||||
# Update the assets bundle to be committed into the repository
|
||||
# and also builds the Escript.
|
||||
build: ["cmd npm run deploy --prefix ./assets", "escript.build"]
|
||||
build: ["cmd npm run deploy --prefix ./assets", "escript.build"],
|
||||
"format.all": ["format", "cmd npm run format --prefix ./assets"]
|
||||
]
|
||||
end
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue