mirror of
				https://github.com/livebook-dev/livebook.git
				synced 2025-10-31 15:56:05 +08:00 
			
		
		
		
	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:
		
							parent
							
								
									aa95d81729
								
							
						
					
					
						commit
						ad999cf9c0
					
				
					 4 changed files with 99 additions and 3 deletions
				
			
		|  | @ -100,6 +100,10 @@ | ||||||
|     @apply appearance-none border-transparent bg-blue-600 hover:bg-blue-700 cursor-pointer rounded-xl; |     @apply appearance-none border-transparent bg-blue-600 hover:bg-blue-700 cursor-pointer rounded-xl; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   .input-select { | ||||||
|  |     @apply w-60; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   .input-label { |   .input-label { | ||||||
|     @apply mb-0.5 text-sm text-gray-800 font-medium; |     @apply mb-0.5 text-sm text-gray-800 font-medium; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -21,7 +21,7 @@ defmodule Livebook.Notebook.Cell.Input do | ||||||
|           props: props() |           props: props() | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|   @type type :: :text | :url | :number | :password | :textarea | :color | :range |   @type type :: :text | :url | :number | :password | :textarea | :color | :range | :select | ||||||
| 
 | 
 | ||||||
|   @typedoc """ |   @typedoc """ | ||||||
|   Additional properties adjusting the given input type. |   Additional properties adjusting the given input type. | ||||||
|  | @ -97,6 +97,7 @@ defmodule Livebook.Notebook.Cell.Input do | ||||||
|   def default_props(type) |   def default_props(type) | ||||||
| 
 | 
 | ||||||
|   def default_props(:range), do: %{min: 0, max: 100, step: 1} |   def default_props(:range), do: %{min: 0, max: 100, step: 1} | ||||||
|  |   def default_props(:select), do: %{options: [""]} | ||||||
|   def default_props(_type), do: %{} |   def default_props(_type), do: %{} | ||||||
| 
 | 
 | ||||||
|   @doc """ |   @doc """ | ||||||
|  |  | ||||||
|  | @ -159,6 +159,26 @@ defmodule LivebookWeb.SessionLive.CellComponent do | ||||||
|     """ |     """ | ||||||
|   end |   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 |   defp cell_input(assigns) do | ||||||
|     ~H""" |     ~H""" | ||||||
|     <input type={html_input_type(@cell_view.input_type)} |     <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(:number), do: "number" | ||||||
|   defp html_input_type(:color), do: "color" |   defp html_input_type(:color), do: "color" | ||||||
|   defp html_input_type(:range), do: "range" |   defp html_input_type(:range), do: "range" | ||||||
|  |   defp html_input_type(:select), do: "select" | ||||||
|   defp html_input_type(_), do: "text" |   defp html_input_type(_), do: "text" | ||||||
| 
 | 
 | ||||||
|   defp cell_body(assigns) do |   defp cell_body(assigns) do | ||||||
|  |  | ||||||
|  | @ -42,7 +42,7 @@ defmodule LivebookWeb.SessionLive.InputCellSettingsComponent do | ||||||
|             <div class="input-label">Name</div> |             <div class="input-label">Name</div> | ||||||
|             <input type="text" class="input" name="attrs[name]" value={@attrs.name} autofocus /> |             <input type="text" class="input" name="attrs[name]" value={@attrs.name} autofocus /> | ||||||
|           </div> |           </div> | ||||||
|           <.extra_fields type={@attrs.type} props={@attrs.props} /> |           <.extra_fields type={@attrs.type} props={@attrs.props} myself={@myself} /> | ||||||
|           <.switch_checkbox |           <.switch_checkbox | ||||||
|             name="attrs[reactive]" |             name="attrs[reactive]" | ||||||
|             label="Reactive (reevaluates dependent cells on change)" |             label="Reactive (reevaluates dependent cells on change)" | ||||||
|  | @ -78,6 +78,46 @@ defmodule LivebookWeb.SessionLive.InputCellSettingsComponent do | ||||||
|     """ |     """ | ||||||
|   end |   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"" |   defp extra_fields(assigns), do: ~H"" | ||||||
| 
 | 
 | ||||||
|   @impl true |   @impl true | ||||||
|  | @ -100,6 +140,24 @@ defmodule LivebookWeb.SessionLive.InputCellSettingsComponent do | ||||||
|     {:noreply, push_patch(socket, to: socket.assigns.return_to)} |     {:noreply, push_patch(socket, to: socket.assigns.return_to)} | ||||||
|   end |   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 |   defp validate_attrs(data, prev_attrs) do | ||||||
|     name = data["name"] |     name = data["name"] | ||||||
|     type = data["type"] |> String.to_existing_atom() |     type = data["type"] |> String.to_existing_atom() | ||||||
|  | @ -126,10 +184,20 @@ defmodule LivebookWeb.SessionLive.InputCellSettingsComponent do | ||||||
|     {valid?, data} |     {valid?, data} | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  |   defp validate_props(data, :select) do | ||||||
|  |     options = data["options"] || [] | ||||||
|  |     valid? = valid_options?(options) | ||||||
|  |     {valid?, %{options: options}} | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|   defp validate_props(_data, _type) do |   defp validate_props(_data, _type) do | ||||||
|     {true, %{}} |     {true, %{}} | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  |   defp valid_options?(options) do | ||||||
|  |     options != [] and options == Enum.uniq(options) | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|   defp parse_number(string) do |   defp parse_number(string) do | ||||||
|     case Float.parse(string) do |     case Float.parse(string) do | ||||||
|       {number, _} -> |       {number, _} -> | ||||||
|  | @ -143,6 +211,7 @@ defmodule LivebookWeb.SessionLive.InputCellSettingsComponent do | ||||||
| 
 | 
 | ||||||
|   defp default_value(:color, _props), do: "#3E64FF" |   defp default_value(:color, _props), do: "#3E64FF" | ||||||
|   defp default_value(:range, %{min: min}), do: to_string(min) |   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 default_value(_type, _props), do: "" | ||||||
| 
 | 
 | ||||||
|   defp input_types do |   defp input_types do | ||||||
|  | @ -153,7 +222,8 @@ defmodule LivebookWeb.SessionLive.InputCellSettingsComponent do | ||||||
|       text: "Text", |       text: "Text", | ||||||
|       textarea: "Textarea", |       textarea: "Textarea", | ||||||
|       url: "URL", |       url: "URL", | ||||||
|       range: "Range" |       range: "Range", | ||||||
|  |       select: "Select" | ||||||
|     ] |     ] | ||||||
|   end |   end | ||||||
| end | end | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue