<.input_label
label={@input.attrs.label}
changed={@changed}
@@ -123,7 +123,7 @@ defmodule LivebookWeb.Output.InputComponent do
/>
<.text_field
- id={@id}
+ id={"#{@id}-input-#{@counter}"}
type="time"
data-el-input
name="html_value"
@@ -143,9 +143,14 @@ defmodule LivebookWeb.Output.InputComponent do
def render(assigns) do
~H"""
-
"""
end
@@ -268,8 +273,28 @@ defmodule LivebookWeb.Output.InputComponent do
"""
end
- defp input_output(%{attrs: %{type: type}} = assigns)
- when type in [:number, :url, :text] do
+ defp input_output(%{attrs: %{type: :number}} = assigns) do
+ ~H"""
+
+ <.text_field
+ type="number"
+ data-el-input
+ id={@id}
+ name="html_value"
+ value={to_string(@value)}
+ phx-debounce={@attrs.debounce}
+ phx-target={@myself}
+ min={@attrs.min}
+ max={@attrs.max}
+ step={@attrs.step}
+ spellcheck="false"
+ autocomplete="off"
+ />
+
+ """
+ end
+
+ defp input_output(%{attrs: %{type: type}} = assigns) when type in [:url, :text] do
~H"""
<.text_field
@@ -312,7 +337,6 @@ defmodule LivebookWeb.Output.InputComponent do
"""
end
- defp html_input_type(:number), do: "number"
defp html_input_type(:url), do: "url"
defp html_input_type(:text), do: "text"
@@ -374,17 +398,15 @@ defmodule LivebookWeb.Output.InputComponent do
{:ok, html_value}
end
- defp parse(html_value, %{type: :number}) do
+ defp parse(html_value, %{type: :number} = attrs) do
if html_value == "" do
{:ok, nil}
else
- case Integer.parse(html_value) do
- {number, ""} ->
- {:ok, number}
-
- _ ->
- {number, ""} = Float.parse(html_value)
- {:ok, number}
+ with {:ok, number} <- parse_number(html_value),
+ true <- in_range?(number, attrs.min, attrs.max) do
+ {:ok, number}
+ else
+ _ -> :error
end
end
end
@@ -461,6 +483,22 @@ defmodule LivebookWeb.Output.InputComponent do
end
end
+ defp parse_number(html_value) do
+ case Integer.parse(html_value) do
+ {number, ""} ->
+ {:ok, number}
+
+ _ ->
+ case Float.parse(html_value) do
+ {number, ""} ->
+ {:ok, number}
+
+ _ ->
+ :error
+ end
+ end
+ end
+
defp truncate_datetime(datetime) do
datetime
|> NaiveDateTime.truncate(:second)
@@ -479,6 +517,10 @@ defmodule LivebookWeb.Output.InputComponent do
(max == nil or struct.compare(datetime, max) != :gt)
end
+ defp in_range?(number, min, max) when is_number(number) do
+ (min == nil or number >= min) and (max == nil or number <= max)
+ end
+
defp report_event(socket, value) do
topic = socket.assigns.input.ref
event = %{value: value, origin: socket.assigns.client_id, type: :change}
diff --git a/mix.lock b/mix.lock
index 4ebf54a4727..8d72edd2086 100644
--- a/mix.lock
+++ b/mix.lock
@@ -44,7 +44,7 @@
"phoenix_html": {:hex, :phoenix_html, "4.2.1", "35279e2a39140068fc03f8874408d58eef734e488fc142153f055c5454fd1c08", [:mix], [], "hexpm", "cff108100ae2715dd959ae8f2a8cef8e20b593f8dfd031c9cba92702cf23e053"},
"phoenix_live_dashboard": {:hex, :phoenix_live_dashboard, "0.8.6", "7b1f0327f54c9eb69845fd09a77accf922f488c549a7e7b8618775eb603a62c7", [:mix], [{:ecto, "~> 3.6.2 or ~> 3.7", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_mysql_extras, "~> 0.5", [hex: :ecto_mysql_extras, repo: "hexpm", optional: true]}, {:ecto_psql_extras, "~> 0.7", [hex: :ecto_psql_extras, repo: "hexpm", optional: true]}, {:ecto_sqlite3_extras, "~> 1.1.7 or ~> 1.2.0", [hex: :ecto_sqlite3_extras, repo: "hexpm", optional: true]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.19 or ~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6 or ~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "1681ab813ec26ca6915beb3414aa138f298e17721dc6a2bde9e6eb8a62360ff6"},
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.6.1", "05df733a09887a005ed0d69a7fc619d376aea2730bf64ce52ac51ce716cc1ef0", [:mix], [{:file_system, "~> 0.2.10 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "74273843d5a6e4fef0bbc17599f33e3ec63f08e69215623a0cd91eea4288e5a0"},
- "phoenix_live_view": {:hex, :phoenix_live_view, "1.1.11", "1b4d8fa56898d93b6f528c89227198a3fce7c5b242819b22ed9e92b73c1bb077", [:mix], [{:igniter, ">= 0.6.16 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:lazy_html, "~> 0.1.0", [hex: :lazy_html, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0 or ~> 1.8.0-rc", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.15", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "266823602e11a54e562ac03a25b3d232d79de12514262db7cfcbb83fdfd8fd57"},
+ "phoenix_live_view": {:hex, :phoenix_live_view, "1.1.24", "1a000a048d5971b61a9efe29a3c4144ca955afd42224998d841c5011a5354838", [:mix], [{:igniter, ">= 0.6.16 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:lazy_html, "~> 0.1.0", [hex: :lazy_html, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0 or ~> 1.8.0-rc", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.15", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "0c724e6c65f197841cac49d73be4e0f9b93a7711eaa52d2d4d1b9f859c329267"},
"phoenix_pubsub": {:hex, :phoenix_pubsub, "2.2.0", "ff3a5616e1bed6804de7773b92cbccfc0b0f473faf1f63d7daf1206c7aeaaa6f", [:mix], [], "hexpm", "adc313a5bf7136039f63cfd9668fde73bba0765e0614cba80c06ac9460ff3e96"},
"phoenix_template": {:hex, :phoenix_template, "1.0.4", "e2092c132f3b5e5b2d49c96695342eb36d0ed514c5b252a77048d5969330d639", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "2c0c81f0e5c6753faf5cca2f229c9709919aba34fab866d3bc05060c9c444206"},
"plug": {:hex, :plug, "1.18.0", "d78df36c41f7e798f2edf1f33e1727eae438e9dd5d809a9997c463a108244042", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "819f9e176d51e44dc38132e132fe0accaf6767eab7f0303431e404da8476cfa2"},