Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion lib/kino/input.ex
Original file line number Diff line number Diff line change
Expand Up @@ -143,23 +143,58 @@ defmodule Kino.Input do

* `:default` - the initial input value. Defaults to `nil`

* `:min` - the minimum value

* `:max` - the maximum value

* `:step` - the input increment

* `:debounce` - determines when input changes are emitted. When
set to `:blur`, the change propagates when the user leaves the
input. When set to a non-negative number of milliseconds, the
change propagates after the specified delay. Defaults to `:blur`
"""
@spec number(String.t(), keyword()) :: t()
def number(label, opts \\ []) when is_binary(label) and is_list(opts) do
min = Keyword.get(opts, :min, nil)
max = Keyword.get(opts, :max, nil)
step = Keyword.get(opts, :step, nil)
default = Keyword.get(opts, :default, nil)
debounce = Keyword.get(opts, :debounce, :blur)

if min && max && min >= max do
raise ArgumentError,
"expected :min to be less than :max, got: #{inspect(min)} and #{inspect(max)}"
end

assert_default_value!(default, "be either number or nil", fn value ->
is_nil(value) or is_number(value)
end)

if (default && min && default < min) || (default && max && default > max) do
raise ArgumentError,
"expected :default to be between :min and :max, got: #{inspect(default)}"
end

assert_default_value!(step, "be either number or nil", fn value ->
is_nil(value) or is_number(value)
end)

if step && step <= 0 do
raise ArgumentError, "expected :step to be positive, got: #{inspect(step)}"
end

assert_debounce_value!(debounce)

new(%{type: :number, label: label, default: default, debounce: debounce})
new(%{
type: :number,
label: label,
default: default,
min: min,
max: max,
step: step,
debounce: debounce
})
end

defp assert_default_value!(value, message, check) do
Expand Down
18 changes: 18 additions & 0 deletions test/kino/input_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,24 @@ defmodule Kino.InputTest do
end

describe "number/2" do
test "raises an error when min is less than max" do
assert_raise ArgumentError, "expected :min to be less than :max, got: 10 and 0", fn ->
Kino.Input.number("Length", min: 10, max: 0)
end
end

test "raises an error when step is negative" do
assert_raise ArgumentError, "expected :step to be positive, got: -1", fn ->
Kino.Input.number("Length", step: -1)
end
end

test "raises an error when the default is out of range" do
assert_raise ArgumentError, "expected :default to be between :min and :max, got: 20", fn ->
Kino.Input.number("Length", min: 0, max: 10, default: 20)
end
end

test "raises an error on invalid default value" do
assert_raise ArgumentError,
~s/expected :default to be either number or nil, got: "10"/,
Expand Down