Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add step param to Number #5047

Merged
merged 12 commits into from
Aug 1, 2023
7 changes: 7 additions & 0 deletions .changeset/plain-ties-pick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@gradio/app": minor
"@gradio/form": minor
"gradio": minor
---

feat:Add `step` param to `Number`
4 changes: 4 additions & 0 deletions gradio/components/number.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ def __init__(
precision: int | None = None,
minimum: float | None = None,
maximum: float | None = None,
step: float | None = None,
hannahblair marked this conversation as resolved.
Show resolved Hide resolved
**kwargs,
):
"""
Expand All @@ -79,10 +80,12 @@ def __init__(
precision: Precision to round input/output to. If set to 0, will round to nearest integer and convert type to int. If None, no rounding happens.
minimum: Minimum value. Only applied when component is used as an input. If a user provides a smaller value, a gr.Error exception is raised by the backend.
maximum: Maximum value. Only applied when component is used as an input. If a user provides a larger value, a gr.Error exception is raised by the backend.
step: The interval between numbers in the input field. If None, a default of 1 is set.
hannahblair marked this conversation as resolved.
Show resolved Hide resolved
"""
self.precision = precision
self.minimum = minimum
self.maximum = maximum
self.step = step

IOComponent.__init__(
self,
Expand Down Expand Up @@ -127,6 +130,7 @@ def get_config(self):
"value": self.value,
"minimum": self.minimum,
"maximum": self.maximum,
"step": self.step,
hannahblair marked this conversation as resolved.
Show resolved Hide resolved
"container": self.container,
**IOComponent.get_config(self),
}
Expand Down
39 changes: 39 additions & 0 deletions js/app/src/components/Number/Number.stories.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<script>
import { Meta, Template, Story } from "@storybook/addon-svelte-csf";
import Number from "./Number.svelte";
</script>

<Meta title="Components/Number" component={Number} />

<Template let:args>
<Number {...args} />
</Template>

<Story
name="Number with min 0 and max 100"
args={{
minimum: 0,
maximum: 100,
}}
/>

<Story
name="Number with step of 10"
args={{
step: 10,
}}
/>

<Story
name="Number in disabled state"
args={{
mode: "static",
}}
/>

<Story
name="Number with hidden label"
args={{
show_label: false,
}}
/>
26 changes: 18 additions & 8 deletions js/app/src/components/Number/Number.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,33 @@
import StatusTracker from "../StatusTracker/StatusTracker.svelte";
import type { LoadingStatus } from "../StatusTracker/types";

export let label: string = "Number";
export let label = "Number";
export let info: string | undefined = undefined;
export let elem_id: string = "";
export let elem_classes: Array<string> = [];
export let visible: boolean = true;
export let container: boolean = true;
export let elem_id = "";
export let elem_classes: string[] = [];
export let visible = true;
export let container = true;
export let scale: number | null = null;
export let min_width: number | undefined = undefined;
export let value: number = 0;
export let value = 0;
export let show_label: boolean;
export let minimum: number | undefined = undefined;
export let maximum: number | undefined = undefined;
export let loading_status: LoadingStatus;
export let mode: "static" | "dynamic";
export let value_is_output: boolean = false;
export let value_is_output = false;
export let step: number | null = null;
</script>

<Block {visible} {elem_id} {elem_classes} padding={container} allow_overflow={false} {scale} {min_width}>
<Block
{visible}
{elem_id}
{elem_classes}
padding={container}
allow_overflow={false}
{scale}
{min_width}
>
<StatusTracker {...loading_status} />

<Number
Expand All @@ -32,6 +41,7 @@
{show_label}
{minimum}
{maximum}
{step}
{container}
disabled={mode === "static"}
on:change
Expand Down
22 changes: 12 additions & 10 deletions js/form/src/Number.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@
import { afterUpdate, createEventDispatcher, tick } from "svelte";
import { BlockTitle } from "@gradio/atoms";

export let value: number = 0;
export let value = 0;
export let minimum: number | undefined = undefined;
export let maximum: number | undefined = undefined;
export let value_is_output: boolean = false;
export let disabled: boolean = false;
export let value_is_output = false;
export let disabled = false;
export let label: string;
export let info: string | undefined = undefined;
export let show_label: boolean = true;
export let container: boolean = true;
export let show_label = true;
export let container = true;
export let step: number | null = 1;

const dispatch = createEventDispatcher<{
change: number;
Expand All @@ -19,7 +20,7 @@
input: undefined;
}>();

function handle_change() {
function handle_change(): void {
if (!isNaN(value) && value !== null) {
dispatch("change", value);
if (!value_is_output) {
Expand All @@ -32,35 +33,36 @@
});
$: value, handle_change();

async function handle_keypress(e: KeyboardEvent) {
async function handle_keypress(e: KeyboardEvent): Promise<void> {
await tick();
if (e.key === "Enter") {
e.preventDefault();
dispatch("submit");
}
}

function handle_blur(e: FocusEvent) {
function handle_blur(e: FocusEvent): void {
dispatch("blur");
}
</script>

<!-- svelte-ignore a11y-label-has-associated-control -->
<label class="block" class:container>
<BlockTitle {show_label} {info}>{label}</BlockTitle>
<input
type="number"
bind:value
min={minimum}
max={maximum}
{step}
on:keypress={handle_keypress}
on:blur={handle_blur}
{disabled}
/>
</label>

<style>
label:not(.container), label:not(.container) > input {
label:not(.container),
label:not(.container) > input {
height: 100%;
border: none;
}
Expand Down
2 changes: 2 additions & 0 deletions test/test_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ def test_component_functions(self):
"value": None,
"name": "number",
"show_label": True,
"step": None,
"label": None,
"minimum": None,
"maximum": None,
Expand Down Expand Up @@ -265,6 +266,7 @@ def test_component_functions_integer(self):
"value": 42,
"name": "number",
"show_label": True,
"step": None,
"label": None,
"minimum": None,
"maximum": None,
Expand Down