Implement checkbox input (#461)

* Implement checkbox input

* Adjustments

Co-authored-by: Jonatan Kłosko <jonatanklosko@gmail.com>
This commit is contained in:
Huynh Tan 2021-07-27 00:59:52 +07:00 committed by GitHub
parent 7dd80489a3
commit e7a8a0775f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 49 additions and 11 deletions

View file

@ -234,7 +234,10 @@ function handleInsertModeChanged(hook, insertMode) {
if (input) {
if (hook.state.insertMode) {
input.focus();
input.selectionStart = input.selectionEnd = input.value.length;
// selectionStart is only supported on text based input
if (input.selectionStart !== null) {
input.selectionStart = input.selectionEnd = input.value.length;
}
} else {
input.blur();
}

View file

@ -21,7 +21,8 @@ defmodule Livebook.Notebook.Cell.Input do
props: props()
}
@type type :: :text | :url | :number | :password | :textarea | :color | :range | :select
@type type ::
:text | :url | :number | :password | :textarea | :color | :range | :select | :checkbox
@typedoc """
Additional properties adjusting the given input type.

View file

@ -151,6 +151,10 @@ defmodule LivebookWeb.Helpers do
@doc """
Renders a checkbox input styled as a switch.
Also, a hidden input with the same name is rendered
alongside the checkbox, so the submitted value is
always either `"true"` or `"false"`.
## Examples
<.switch_checkbox
@ -159,13 +163,30 @@ defmodule LivebookWeb.Helpers do
checked={@likes_cats} />
"""
def switch_checkbox(assigns) do
assigns = assign_new(assigns, :disabled, fn -> false end)
assigns =
assigns
|> assign_new(:label, fn -> nil end)
|> assign_new(:disabled, fn -> false end)
|> assign_new(:class, fn -> "" end)
|> assign(
:attrs,
assigns_to_attributes(assigns, [:label, :name, :checked, :disabled, :class])
)
~H"""
<div class="flex space-x-3 items-center justify-between">
<span class="text-gray-700"><%= @label %></span>
<%= if @label do %>
<span class="text-gray-700"><%= @label %></span>
<% end %>
<label class={"switch-button #{if(@disabled, do: "switch-button--disabled")}"}>
<input class="switch-button__checkbox" type="checkbox" name={@name} checked={@checked} />
<input type="hidden" value="false" name={@name} />
<input
type="checkbox"
value="true"
class={"switch-button__checkbox #{@class}"}
name={@name}
checked={@checked}
{@attrs} />
<div class="switch-button__bg"></div>
</label>
</div>

View file

@ -179,6 +179,17 @@ defmodule LivebookWeb.SessionLive.CellComponent do
"""
end
defp cell_input(%{cell_view: %{input_type: :checkbox}} = assigns) do
~H"""
<div class="mt-1">
<.switch_checkbox
data-element="input"
name="value"
checked={@cell_view.value == "true"} />
</div>
"""
end
defp cell_input(assigns) do
~H"""
<input type={html_input_type(@cell_view.input_type)}

View file

@ -35,8 +35,8 @@ defmodule LivebookWeb.SessionLive.DeleteSectionComponent do
end
@impl true
def handle_event("delete", params, socket) do
delete_cells? = Map.has_key?(params, "delete_cells")
def handle_event("delete", %{"delete_cells" => delete_cells}, socket) do
delete_cells? = delete_cells == "true"
Livebook.Session.delete_section(
socket.assigns.session_id,

View file

@ -50,7 +50,7 @@ defmodule LivebookWeb.SessionLive.ElixirCellSettingsComponent do
end
defp update_metadata(metadata, form_data) do
if Map.has_key?(form_data, "disable_formatting") do
if form_data["disable_formatting"] == "true" do
Map.put(metadata, "disable_formatting", true)
else
Map.delete(metadata, "disable_formatting")

View file

@ -161,7 +161,7 @@ defmodule LivebookWeb.SessionLive.InputCellSettingsComponent do
defp validate_attrs(data, prev_attrs) do
name = data["name"]
type = data["type"] |> String.to_existing_atom()
reactive = Map.has_key?(data, "reactive")
reactive = data["reactive"] == "true"
{props_valid?, props} =
if type == prev_attrs.type do
@ -209,6 +209,7 @@ defmodule LivebookWeb.SessionLive.InputCellSettingsComponent do
end
end
defp default_value(:checkbox, _props), do: "false"
defp default_value(:color, _props), do: "#3E64FF"
defp default_value(:range, %{min: min}), do: to_string(min)
defp default_value(:select, %{options: [option | _]}), do: option
@ -216,6 +217,7 @@ defmodule LivebookWeb.SessionLive.InputCellSettingsComponent do
defp input_types do
[
checkbox: "Checkbox",
color: "Color",
number: "Number",
password: "Password",

View file

@ -226,8 +226,8 @@ defmodule LivebookWeb.SessionLive.ShortcutsComponent do
end
@impl true
def handle_event("settings", params, socket) do
basic? = Map.has_key?(params, "basic")
def handle_event("settings", %{"basic" => basic}, socket) do
basic? = basic == "true"
{:noreply, assign(socket, :basic, basic?)}
end
end