Skip to content

Commit 0c06dcd

Browse files
feat: adds autofocus to Input field (#570)
# Motivation We want to be able to set `focus` on the `Input` component. Since enabling `autofocus` is not recommended, we aim to make it possible to bind the input element. This way, we can set the focus programmaticcly and improve the user experience of our application. # Changes - enables to set focus on `Input` component --------- Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 03d1726 commit 0c06dcd

File tree

4 files changed

+33
-2
lines changed

4 files changed

+33
-2
lines changed

src/lib/components/Input.svelte

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
export let testId: string | undefined = undefined;
1616
export let decimals = 8;
1717
export let ignore1Password = true;
18+
export let inputElement: HTMLInputElement | undefined = undefined;
1819
1920
const dispatch = createEventDispatcher();
2021
@@ -29,8 +30,6 @@
2930
// showInfo = $$slots.label || $$slots.end
3031
export let showInfo = true;
3132
32-
let inputElement: HTMLInputElement | undefined;
33-
3433
$: step = inputType === "number" ? (step ?? "any") : undefined;
3534
$: autocomplete =
3635
inputType !== "number" ? (autocomplete ?? "off") : undefined;

src/routes/(split)/components/input/+page.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ The input component is a wrapper to the HTML input element with custom styling a
3434
| `showInfo` | Display additional information related to the input. Should be used in addition to slots. | `boolean` | `false` |
3535
| `testId` | Add a `data-tid` attribute to the DOM, useful for test purpose. | `string` or `undefined` | `undefined` |
3636
| `ignore1Password` | Tell 1Password it should ignore the field (Reference: 1Password [documentation](https://developer.1password.com/docs/web/compatible-website-design/)) | `boolean` | `true` |
37+
| `inputElement` | HTML input element | `HTMLInputElement` or `undefined` | `undefined` |
3738

3839
### Notes
3940

src/tests/lib/components/Input.spec.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import Input from "$lib/components/Input.svelte";
22
import { assertNonNullish, isNullish, nonNullish } from "@dfinity/utils";
33
import { fireEvent, render } from "@testing-library/svelte";
44
import { tick } from "svelte";
5+
import InputElementTest from "./InputElementTest.svelte";
56
import InputTest from "./InputTest.svelte";
67
import InputValueTest from "./InputValueTest.svelte";
78

@@ -538,4 +539,18 @@ describe("Input", () => {
538539
});
539540
}));
540541
});
542+
543+
it("should bind input element", async () => {
544+
const { container } = render(InputElementTest, {
545+
props,
546+
});
547+
548+
const input: HTMLInputElement | null = container.querySelector("input");
549+
expect(input === document.activeElement).toBe(false);
550+
551+
const testBind: HTMLButtonElement | null = container.querySelector("#test");
552+
testBind && testBind.click();
553+
554+
expect(input === document.activeElement).toBe(true);
555+
});
541556
});
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<script lang="ts">
2+
import Input from "$lib/components/Input.svelte";
3+
4+
export let name: string;
5+
export let placeholder = "test.placeholder";
6+
7+
let inputField: HTMLInputElement | undefined;
8+
9+
const changeFocus = () => {
10+
inputField.focus();
11+
};
12+
</script>
13+
14+
<button on:click={changeFocus} id="test" />
15+
16+
<Input bind:inputElement={inputField} {name} {placeholder} />

0 commit comments

Comments
 (0)