mirror of
https://github.com/gradio-app/gradio.git
synced 2025-03-01 11:45:36 +08:00
Enhancement: Add focus event to textbox and number component (#5005)
* Add focus event to textbox and number component * add changeset * Combine Blurrable and Focusable into Focusable event * Add focus and blur to Dropdown and Colorpicker components * add focus to home page template * Add Focus to doc * Fix linting error * fixes --------- Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com> Co-authored-by: Abubakar Abid <abubakar@huggingface.co> Co-authored-by: Ali Abid <aabid94@gmail.com>
This commit is contained in:
parent
95ea19d65f
commit
f5539c7618
7
.changeset/silver-signs-speak.md
Normal file
7
.changeset/silver-signs-speak.md
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
"@gradio/app": minor
|
||||
"@gradio/form": minor
|
||||
"gradio": minor
|
||||
---
|
||||
|
||||
feat:Enhancement: Add focus event to textbox and number component
|
@ -9,8 +9,8 @@ from gradio_client.serializing import StringSerializable
|
||||
|
||||
from gradio.components.base import IOComponent, _Keywords
|
||||
from gradio.events import (
|
||||
Blurrable,
|
||||
Changeable,
|
||||
Focusable,
|
||||
Inputable,
|
||||
Submittable,
|
||||
)
|
||||
@ -20,7 +20,7 @@ set_documentation_group("component")
|
||||
|
||||
@document()
|
||||
class ColorPicker(
|
||||
Changeable, Inputable, Submittable, Blurrable, IOComponent, StringSerializable
|
||||
Changeable, Inputable, Submittable, Focusable, IOComponent, StringSerializable
|
||||
):
|
||||
"""
|
||||
Creates a color picker for user to select a color as string input.
|
||||
|
@ -11,9 +11,9 @@ from gradio_client.serializing import SimpleSerializable
|
||||
from gradio.components.base import FormComponent, IOComponent, _Keywords
|
||||
from gradio.deprecation import warn_style_method_deprecation
|
||||
from gradio.events import (
|
||||
Blurrable,
|
||||
Changeable,
|
||||
EventListenerMethod,
|
||||
Focusable,
|
||||
Inputable,
|
||||
Selectable,
|
||||
)
|
||||
@ -27,7 +27,7 @@ class Dropdown(
|
||||
Changeable,
|
||||
Inputable,
|
||||
Selectable,
|
||||
Blurrable,
|
||||
Focusable,
|
||||
IOComponent,
|
||||
SimpleSerializable,
|
||||
):
|
||||
|
@ -11,8 +11,8 @@ from gradio_client.serializing import NumberSerializable
|
||||
|
||||
from gradio.components.base import FormComponent, IOComponent, _Keywords
|
||||
from gradio.events import (
|
||||
Blurrable,
|
||||
Changeable,
|
||||
Focusable,
|
||||
Inputable,
|
||||
Submittable,
|
||||
)
|
||||
@ -28,7 +28,7 @@ class Number(
|
||||
Changeable,
|
||||
Inputable,
|
||||
Submittable,
|
||||
Blurrable,
|
||||
Focusable,
|
||||
IOComponent,
|
||||
NumberSerializable,
|
||||
NeighborInterpretable,
|
||||
|
@ -15,9 +15,9 @@ from gradio.components.base import (
|
||||
)
|
||||
from gradio.deprecation import warn_style_method_deprecation
|
||||
from gradio.events import (
|
||||
Blurrable,
|
||||
Changeable,
|
||||
EventListenerMethod,
|
||||
Focusable,
|
||||
Inputable,
|
||||
Selectable,
|
||||
Submittable,
|
||||
@ -34,7 +34,7 @@ class Textbox(
|
||||
Inputable,
|
||||
Selectable,
|
||||
Submittable,
|
||||
Blurrable,
|
||||
Focusable,
|
||||
IOComponent,
|
||||
StringSerializable,
|
||||
TokenInterpretable,
|
||||
|
@ -286,9 +286,15 @@ class Recordable(EventListener):
|
||||
"""
|
||||
|
||||
|
||||
@document("*blur", inherit=True)
|
||||
class Blurrable(EventListener):
|
||||
@document("*focus", "*blur", inherit=True)
|
||||
class Focusable(EventListener):
|
||||
def __init__(self):
|
||||
self.focus = EventListenerMethod(self, "focus")
|
||||
"""
|
||||
This listener is triggered when the component is focused (e.g. when the user clicks inside a textbox).
|
||||
This method can be used when this component is in a Gradio Blocks.
|
||||
"""
|
||||
|
||||
self.blur = EventListenerMethod(self, "blur")
|
||||
"""
|
||||
This listener is triggered when the component's is unfocused/blurred (e.g. when the user clicks outside of a textbox).
|
||||
|
@ -34,6 +34,7 @@
|
||||
on:input
|
||||
on:submit
|
||||
on:blur
|
||||
on:focus
|
||||
disabled={mode === "static"}
|
||||
/>
|
||||
</Block>
|
||||
|
@ -48,6 +48,7 @@
|
||||
on:input
|
||||
on:select
|
||||
on:blur
|
||||
on:focus
|
||||
disabled={mode === "static"}
|
||||
/>
|
||||
</Block>
|
||||
|
@ -48,5 +48,6 @@
|
||||
on:input
|
||||
on:submit
|
||||
on:blur
|
||||
on:focus
|
||||
/>
|
||||
</Block>
|
||||
|
@ -54,6 +54,7 @@
|
||||
on:submit
|
||||
on:blur
|
||||
on:select
|
||||
on:focus
|
||||
disabled={mode === "static"}
|
||||
/>
|
||||
</Block>
|
||||
|
@ -14,6 +14,7 @@
|
||||
input: undefined;
|
||||
submit: undefined;
|
||||
blur: undefined;
|
||||
focus: undefined;
|
||||
}>();
|
||||
|
||||
function handle_change() {
|
||||
@ -22,6 +23,7 @@
|
||||
dispatch("input");
|
||||
}
|
||||
}
|
||||
|
||||
afterUpdate(() => {
|
||||
value_is_output = false;
|
||||
});
|
||||
@ -31,7 +33,7 @@
|
||||
<!-- svelte-ignore a11y-label-has-associated-control -->
|
||||
<label class="block">
|
||||
<BlockTitle {show_label} {info}>{label}</BlockTitle>
|
||||
<input type="color" on:blur bind:value {disabled} />
|
||||
<input type="color" bind:value on:focus on:blur {disabled} />
|
||||
</label>
|
||||
|
||||
<style>
|
||||
|
@ -22,6 +22,7 @@
|
||||
input: undefined;
|
||||
select: SelectData;
|
||||
blur: undefined;
|
||||
focus: undefined;
|
||||
}>();
|
||||
|
||||
let inputValue: string | undefined,
|
||||
@ -86,6 +87,33 @@
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
function handle_blur(e: FocusEvent) {
|
||||
if (multiselect) {
|
||||
inputValue = "";
|
||||
} else if (!allow_custom_value) {
|
||||
if (value !== inputValue) {
|
||||
if (typeof value === "string" && inputValue == "") {
|
||||
inputValue = value;
|
||||
} else {
|
||||
value = undefined;
|
||||
inputValue = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
showOptions = false;
|
||||
dispatch("blur");
|
||||
}
|
||||
|
||||
function handle_focus(e: FocusEvent){
|
||||
dispatch("focus");
|
||||
showOptions = !showOptions;
|
||||
if (showOptions) {
|
||||
filtered = choices;
|
||||
} else {
|
||||
filterInput.blur();
|
||||
}
|
||||
}
|
||||
|
||||
function handleOptionMousedown(e: any): void {
|
||||
const option = e.detail.target.dataset.value;
|
||||
if (allow_custom_value) {
|
||||
@ -113,15 +141,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
function handleFocus(): void {
|
||||
showOptions = !showOptions;
|
||||
if (showOptions) {
|
||||
filtered = choices;
|
||||
} else {
|
||||
filterInput.blur();
|
||||
}
|
||||
}
|
||||
|
||||
function handleKeydown(e: any) {
|
||||
if (e.key === "Enter" && activeOption != undefined) {
|
||||
if (!multiselect) {
|
||||
@ -208,28 +227,14 @@
|
||||
autocomplete="off"
|
||||
bind:value={inputValue}
|
||||
bind:this={filterInput}
|
||||
on:focus={handleFocus}
|
||||
on:keydown={handleKeydown}
|
||||
on:keyup={() => {
|
||||
if (allow_custom_value) {
|
||||
value = inputValue;
|
||||
}
|
||||
}}
|
||||
on:blur={() => {
|
||||
if (multiselect) {
|
||||
inputValue = "";
|
||||
} else if (!allow_custom_value) {
|
||||
if (value !== inputValue) {
|
||||
if (typeof value === "string" && inputValue == "") {
|
||||
inputValue = value;
|
||||
} else {
|
||||
value = undefined;
|
||||
inputValue = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
showOptions = false;
|
||||
}}
|
||||
on:blur={handle_blur}
|
||||
on:focus={handle_focus}
|
||||
/>
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div
|
||||
|
@ -18,6 +18,7 @@
|
||||
submit: undefined;
|
||||
blur: undefined;
|
||||
input: undefined;
|
||||
focus: undefined;
|
||||
}>();
|
||||
|
||||
function handle_change(): void {
|
||||
@ -40,10 +41,6 @@
|
||||
dispatch("submit");
|
||||
}
|
||||
}
|
||||
|
||||
function handle_blur(e: FocusEvent): void {
|
||||
dispatch("blur");
|
||||
}
|
||||
</script>
|
||||
|
||||
<label class="block" class:container>
|
||||
@ -55,7 +52,8 @@
|
||||
max={maximum}
|
||||
{step}
|
||||
on:keypress={handle_keypress}
|
||||
on:blur={handle_blur}
|
||||
on:blur
|
||||
on:focus
|
||||
{disabled}
|
||||
/>
|
||||
</label>
|
||||
|
@ -33,6 +33,7 @@
|
||||
blur: undefined;
|
||||
select: SelectData;
|
||||
input: undefined;
|
||||
focus: undefined;
|
||||
}>();
|
||||
|
||||
function handle_change() {
|
||||
@ -46,10 +47,6 @@
|
||||
});
|
||||
$: value, handle_change();
|
||||
|
||||
function handle_blur() {
|
||||
dispatch("blur");
|
||||
}
|
||||
|
||||
async function handle_copy() {
|
||||
if ("clipboard" in navigator) {
|
||||
await navigator.clipboard.writeText(value);
|
||||
@ -153,8 +150,9 @@
|
||||
{disabled}
|
||||
{autofocus}
|
||||
on:keypress={handle_keypress}
|
||||
on:blur={handle_blur}
|
||||
on:blur
|
||||
on:select={handle_select}
|
||||
on:focus
|
||||
style={text_align ? "text-align: " + text_align : ""}
|
||||
/>
|
||||
{:else if type === "password"}
|
||||
@ -168,8 +166,9 @@
|
||||
{disabled}
|
||||
{autofocus}
|
||||
on:keypress={handle_keypress}
|
||||
on:blur={handle_blur}
|
||||
on:blur
|
||||
on:select={handle_select}
|
||||
on:focus
|
||||
autocomplete=""
|
||||
/>
|
||||
{:else if type === "email"}
|
||||
@ -183,8 +182,9 @@
|
||||
{disabled}
|
||||
{autofocus}
|
||||
on:keypress={handle_keypress}
|
||||
on:blur={handle_blur}
|
||||
on:blur
|
||||
on:select={handle_select}
|
||||
on:focus
|
||||
autocomplete="email"
|
||||
/>
|
||||
{/if}
|
||||
@ -208,8 +208,9 @@
|
||||
{disabled}
|
||||
{autofocus}
|
||||
on:keypress={handle_keypress}
|
||||
on:blur={handle_blur}
|
||||
on:blur
|
||||
on:select={handle_select}
|
||||
on:focus
|
||||
style={text_align ? "text-align: " + text_align : ""}
|
||||
/>
|
||||
{/if}
|
||||
|
@ -1,4 +1,4 @@
|
||||
lockfileVersion: '6.0'
|
||||
lockfileVersion: '6.1'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
|
@ -72,6 +72,7 @@ ordered_events = [
|
||||
"Pause()",
|
||||
"Stream()",
|
||||
"Blur()",
|
||||
"Focus()",
|
||||
"Upload()",
|
||||
]
|
||||
|
||||
|
@ -323,6 +323,7 @@
|
||||
<th class="p-3 font-normal bg-white border-t">Pause</th>
|
||||
<th class="p-3 font-normal bg-white border-t">Stream</th>
|
||||
<th class="p-3 font-normal bg-white border-t">Blur</th>
|
||||
<th class="p-3 font-normal bg-white border-t">Focus</th>
|
||||
<th class="p-3 font-normal bg-white border-t border-r">Upload</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
Loading…
Reference in New Issue
Block a user