Skip to content

Commit

Permalink
v0.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
metonym committed Jan 1, 2021
1 parent 0cf1f33 commit 5e9def9
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 8 deletions.
7 changes: 5 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

- `focusNextEmptyInput`
- `focusInput`
- Number-only variant

## [0.2.0](https://github.com/metonym/svelte-pincode/releases/tag/v0.2.0) - 2021-01-01

- Add `focusFirstInput`, `focusNextEmptyInput`, `focusLastInput` methods

## [0.1.0](https://github.com/metonym/svelte-pincode/releases/tag/v0.1.0) - 2021-01-01

Expand Down
85 changes: 82 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[![NPM][npm]][npm-url]

> Declarative pincode component for Svelte.
> Pincode component for Svelte.
Try it in the [Svelte REPL](https://svelte.dev/repl/2841eef46bfb49c4a848a2a063602e5d?version=3.31.0).

Expand Down Expand Up @@ -123,9 +123,88 @@ Type in some initial values and then try setting or clearing the code using the
<div>code: <code>{JSON.stringify(passcode)}</code></div>
<button type="button" on:click={() => passcode = ['1', '2', '3', '4']}>Set code</button>
<button type="button" on:click={() => passcode = ['1', '2', '3', '4']}>
Set code
</button>
<button type="button" on:click={() => passcode = ['', '', '', '']}>Clear code</button>
<button type="button" on:click={() => passcode = ['', '', '', '']}>
Clear code
</button>
```
<!-- prettier-ignore-end -->

### Focus first input

To programmatically focus the first input, invoke the `focusFirstInput` method on a component reference.

<!-- prettier-ignore-start -->
```svelte
<script>
let ref;
</script>
<Pincode bind:this={ref}>
<PincodeInput />
<PincodeInput />
<PincodeInput />
<PincodeInput />
</Pincode>
<br />
<button type="button" on:click={ref.focusFirstInput}>
Focus first input
</button>
```
<!-- prettier-ignore-end -->

### Focus next empty input

To focus the next input with no value, invoke the `focusNextEmptyInput` method.

<!-- prettier-ignore-start -->
```svelte
<script>
let pincodeRef;
</script>
<Pincode code={["9", "9"]} bind:this={pincodeRef}>
<PincodeInput />
<PincodeInput />
<PincodeInput />
<PincodeInput />
</Pincode>
<br />
<button type="button" on:click={pincodeRef.focusNextEmptyInput}>
Focus next empty input
</button>
```
<!-- prettier-ignore-end -->

### Focus last input

To focus the last input, invoke the `focusLastInput` method.

<!-- prettier-ignore-start -->
```svelte
<script>
let passcodeRef;
</script>
<Pincode bind:this={passcodeRef}>
<PincodeInput />
<PincodeInput />
<PincodeInput />
<PincodeInput />
</Pincode>
<br />
<button type="button" on:click={passcodeRef.focusLastInput}>
Focus last input
</button>
```
<!-- prettier-ignore-end -->

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"name": "svelte-pincode",
"version": "0.1.0",
"version": "0.2.0",
"license": "MIT",
"description": "Declarative pincode component for Svelte",
"description": "Pincode component for Svelte",
"author": "Eric Liu (https://github.com/metonym)",
"svelte": "./src/index.js",
"main": "./lib/index.js",
Expand Down
20 changes: 20 additions & 0 deletions src/Pincode.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,26 @@
export let value = "";
/** @type {() => void} */
export const focusFirstInput = () => {
ref.querySelector("input").focus();
};
/** @type {() => void} */
export const focusNextEmptyInput = () => {
for (const input of ref.querySelectorAll("input")) {
if (input.value.length === 0) {
input.focus();
break;
}
}
};
/** @type {() => void} */
export const focusLastInput = () => {
ref.querySelector("input:last-of-type").focus();
};
import { setContext, createEventDispatcher } from "svelte";
import { writable, derived } from "svelte/store";
Expand Down
10 changes: 10 additions & 0 deletions test.svelte
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
<script lang="ts">
import { onMount } from "svelte";
import { Pincode, PincodeInput } from "./types";
import { Code } from "./types/Pincode";
const correctCode = "1234";
let ref: Pincode;
let code: Code = [];
let value = "";
$: complete = value.length === correctCode.length;
$: success = complete && value === correctCode;
$: error = complete && !success;
onMount(() => {
ref.focusFirstInput();
ref.focusNextEmptyInput();
ref.focusLastInput();
});
</script>

<Pincode
bind:this="{ref}"
bind:code
bind:value
on:complete="{(e) => {
Expand Down
20 changes: 19 additions & 1 deletion types/Pincode.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,28 @@ export interface PincodeProps extends svelte.JSX.HTMLAttributes<HTMLElementTagNa
* @default ""
*/
value?: string;

/**
* @constant
* @default () => { ref.querySelector("input").focus(); }
*/
focusFirstInput?: () => void;

/**
* @constant
* @default () => { for (const input of ref.querySelectorAll("input")) { if (input.value.length === 0) { input.focus(); break; } } }
*/
focusNextEmptyInput?: () => void;

/**
* @constant
* @default () => { ref.querySelector("input:last-of-type").focus(); }
*/
focusLastInput?: () => void;
}

export default class Pincode extends SvelteComponentTyped<
PincodeProps,
{ complete: CustomEvent<{ code: Code }> },
{ complete: CustomEvent<{ code: Code; value: string }> },
{ default: {} }
> {}

0 comments on commit 5e9def9

Please sign in to comment.