mirror of
https://github.com/gradio-app/gradio.git
synced 2025-04-06 12:30:29 +08:00
Add step
param to Number
(#5047)
* add step param to number component * add changeset * fix test * fix BE test * fix test again * update number.py * fix test * test fix --------- Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
This commit is contained in:
parent
6693660a79
commit
883ac364f6
7
.changeset/plain-ties-pick.md
Normal file
7
.changeset/plain-ties-pick.md
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
"@gradio/app": minor
|
||||
"@gradio/form": minor
|
||||
"gradio": minor
|
||||
---
|
||||
|
||||
feat:Add `step` param to `Number`
|
@ -60,6 +60,7 @@ class Number(
|
||||
precision: int | None = None,
|
||||
minimum: float | None = None,
|
||||
maximum: float | None = None,
|
||||
step: float = 1,
|
||||
**kwargs,
|
||||
):
|
||||
"""
|
||||
@ -79,10 +80,12 @@ class Number(
|
||||
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 allowed numbers in the component. Can be used along with optional parameters `minimum` and `maximum` to create a range of legal values starting from `minimum` and incrementing according to this parameter.
|
||||
"""
|
||||
self.precision = precision
|
||||
self.minimum = minimum
|
||||
self.maximum = maximum
|
||||
self.step = step
|
||||
|
||||
IOComponent.__init__(
|
||||
self,
|
||||
@ -127,6 +130,7 @@ class Number(
|
||||
"value": self.value,
|
||||
"minimum": self.minimum,
|
||||
"maximum": self.maximum,
|
||||
"step": self.step,
|
||||
"container": self.container,
|
||||
**IOComponent.get_config(self),
|
||||
}
|
||||
@ -136,6 +140,7 @@ class Number(
|
||||
value: float | Literal[_Keywords.NO_VALUE] | None = _Keywords.NO_VALUE,
|
||||
minimum: float | None = None,
|
||||
maximum: float | None = None,
|
||||
step: float = 1,
|
||||
label: str | None = None,
|
||||
info: str | None = None,
|
||||
show_label: bool | None = None,
|
||||
@ -156,6 +161,7 @@ class Number(
|
||||
"value": value,
|
||||
"minimum": minimum,
|
||||
"maximum": maximum,
|
||||
"step": step,
|
||||
"interactive": interactive,
|
||||
"__type__": "update",
|
||||
}
|
||||
|
39
js/app/src/components/Number/Number.stories.svelte
Normal file
39
js/app/src/components/Number/Number.stories.svelte
Normal file
@ -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,
|
||||
}}
|
||||
/>
|
@ -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
|
||||
@ -32,6 +41,7 @@
|
||||
{show_label}
|
||||
{minimum}
|
||||
{maximum}
|
||||
{step}
|
||||
{container}
|
||||
disabled={mode === "static"}
|
||||
on:change
|
||||
|
@ -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;
|
||||
@ -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) {
|
||||
@ -32,7 +33,7 @@
|
||||
});
|
||||
$: 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();
|
||||
@ -40,12 +41,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@ -53,6 +53,7 @@
|
||||
bind:value
|
||||
min={minimum}
|
||||
max={maximum}
|
||||
{step}
|
||||
on:keypress={handle_keypress}
|
||||
on:blur={handle_blur}
|
||||
{disabled}
|
||||
@ -60,7 +61,8 @@
|
||||
</label>
|
||||
|
||||
<style>
|
||||
label:not(.container), label:not(.container) > input {
|
||||
label:not(.container),
|
||||
label:not(.container) > input {
|
||||
height: 100%;
|
||||
border: none;
|
||||
}
|
||||
|
@ -216,6 +216,7 @@ class TestNumber:
|
||||
"value": None,
|
||||
"name": "number",
|
||||
"show_label": True,
|
||||
"step": 1,
|
||||
"label": None,
|
||||
"minimum": None,
|
||||
"maximum": None,
|
||||
@ -265,6 +266,7 @@ class TestNumber:
|
||||
"value": 42,
|
||||
"name": "number",
|
||||
"show_label": True,
|
||||
"step": 1,
|
||||
"label": None,
|
||||
"minimum": None,
|
||||
"maximum": None,
|
||||
|
Loading…
x
Reference in New Issue
Block a user