Added input select (#448)

* Added range input (Slider)
* Added range input (Slider)
* Custom css to range input

* Formatting correction

* Defined min and max values of input range

* Revert "Defined min and max values of input range"

This reverts commit 815167ab0f.

* Added input select

* working with a options like list

* Formatting correction

* swapped li for inputs in input settings

* Removed unused attribute

* Final adjustments

Co-authored-by: Jonatan Kłosko <jonatanklosko@gmail.com>
This commit is contained in:
Jean Carlos 2021-07-18 14:01:44 -03:00 committed by GitHub
parent aa95d81729
commit ad999cf9c0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 99 additions and 3 deletions

View file

@ -100,6 +100,10 @@
@apply appearance-none border-transparent bg-blue-600 hover:bg-blue-700 cursor-pointer rounded-xl;
}
.input-select {
@apply w-60;
}
.input-label {
@apply mb-0.5 text-sm text-gray-800 font-medium;
}

View file

@ -21,7 +21,7 @@ defmodule Livebook.Notebook.Cell.Input do
props: props()
}
@type type :: :text | :url | :number | :password | :textarea | :color | :range
@type type :: :text | :url | :number | :password | :textarea | :color | :range | :select
@typedoc """
Additional properties adjusting the given input type.
@ -97,6 +97,7 @@ defmodule Livebook.Notebook.Cell.Input do
def default_props(type)
def default_props(:range), do: %{min: 0, max: 100, step: 1}
def default_props(:select), do: %{options: [""]}
def default_props(_type), do: %{}
@doc """

View file

@ -159,6 +159,26 @@ defmodule LivebookWeb.SessionLive.CellComponent do
"""
end
defp cell_input(%{cell_view: %{input_type: :select}} = assigns) do
~H"""
<div class="flex items-center space-x-2">
<select
data-element="input"
spellcheck="false"
phx-debounce="300"
class="input input-select"
tabindex="-1"
name="value">
<%= for option <- @cell_view.props.options do %>
<option value={option} selected={option == @cell_view.value}>
<%= option %>
</option>
<% end %>
</select>
</div>
"""
end
defp cell_input(assigns) do
~H"""
<input type={html_input_type(@cell_view.input_type)}
@ -177,6 +197,7 @@ defmodule LivebookWeb.SessionLive.CellComponent do
defp html_input_type(:number), do: "number"
defp html_input_type(:color), do: "color"
defp html_input_type(:range), do: "range"
defp html_input_type(:select), do: "select"
defp html_input_type(_), do: "text"
defp cell_body(assigns) do

View file

@ -42,7 +42,7 @@ defmodule LivebookWeb.SessionLive.InputCellSettingsComponent do
<div class="input-label">Name</div>
<input type="text" class="input" name="attrs[name]" value={@attrs.name} autofocus />
</div>
<.extra_fields type={@attrs.type} props={@attrs.props} />
<.extra_fields type={@attrs.type} props={@attrs.props} myself={@myself} />
<.switch_checkbox
name="attrs[reactive]"
label="Reactive (reevaluates dependent cells on change)"
@ -78,6 +78,46 @@ defmodule LivebookWeb.SessionLive.InputCellSettingsComponent do
"""
end
defp extra_fields(%{type: :select} = assigns) do
~H"""
<div class="flex flex-col">
<div class="input-label mb-0">Options</div>
<div class="my-2 flex flex-col space-y-2">
<%= for {option, idx} <- Enum.with_index(@props.options) do %>
<div class="flex items-center space-x-2">
<input
type="text"
class="input"
name="attrs[props][options][]"
value={option} />
<button
class="button button-gray button-square-icon"
type="button"
tabindex="-1"
phx-target={@myself}
phx-click="select_options_action"
phx-value-action="delete"
phx-value-index={idx}
disabled={length(@props.options) == 1}>
<.remix_icon icon="delete-bin-6-line" />
</button>
</div>
<% end %>
</div>
<div>
<button
class="button button-outlined-gray"
type="button"
phx-target={@myself}
phx-click="select_options_action"
phx-value-action="add">
Add
</button>
</div>
</div>
"""
end
defp extra_fields(assigns), do: ~H""
@impl true
@ -100,6 +140,24 @@ defmodule LivebookWeb.SessionLive.InputCellSettingsComponent do
{:noreply, push_patch(socket, to: socket.assigns.return_to)}
end
def handle_event("select_options_action", params, socket) do
{action, params} = Map.pop!(params, "action")
attrs = socket.assigns.attrs
options = select_options_action(action, params, attrs.props.options)
attrs = put_in(attrs.props.options, options)
valid? = valid_options?(options)
{:noreply, socket |> assign(attrs: attrs) |> assign(valid: valid?)}
end
defp select_options_action("add", _params, options) do
options ++ [""]
end
defp select_options_action("delete", %{"index" => index}, options) do
index = String.to_integer(index)
List.delete_at(options, index)
end
defp validate_attrs(data, prev_attrs) do
name = data["name"]
type = data["type"] |> String.to_existing_atom()
@ -126,10 +184,20 @@ defmodule LivebookWeb.SessionLive.InputCellSettingsComponent do
{valid?, data}
end
defp validate_props(data, :select) do
options = data["options"] || []
valid? = valid_options?(options)
{valid?, %{options: options}}
end
defp validate_props(_data, _type) do
{true, %{}}
end
defp valid_options?(options) do
options != [] and options == Enum.uniq(options)
end
defp parse_number(string) do
case Float.parse(string) do
{number, _} ->
@ -143,6 +211,7 @@ defmodule LivebookWeb.SessionLive.InputCellSettingsComponent do
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
defp default_value(_type, _props), do: ""
defp input_types do
@ -153,7 +222,8 @@ defmodule LivebookWeb.SessionLive.InputCellSettingsComponent do
text: "Text",
textarea: "Textarea",
url: "URL",
range: "Range"
range: "Range",
select: "Select"
]
end
end