Skip to content

Commit

Permalink
feat: support multiple keys
Browse files Browse the repository at this point in the history
  • Loading branch information
metonym committed Jan 25, 2022
1 parent 9678d8c commit abe1960
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 21 deletions.
1 change: 0 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- dispatched events "focus", "afterfocus"
- support a combination of keys (e.g., "command + k")
- support multiple keys (e.g., `["s", "/"]`)
- support option to customize selected text range (select all vs. cursor at end)

## [0.2.4](https://github.com/metonym/svelte-focus-key/releases/tag/v0.2.4) - 2021-12-15
Expand Down
30 changes: 24 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,22 @@ The default focus key is the forward slash (`/`). Customize the key using the `k
<FocusKey element={textarea} key="s" />
```

### Multiple focus keys

The `key` prop can also accept an array of keys.

```svelte
<script>
import FocusKey from "svelte-focus-key";
let node;
</script>
<input bind:this={node} placeholder={'Press "a" or "b"'} />
<FocusKey element={node} key={["a", "b"]} />
```

### Select text on focus

Set `selectText` to `true` to select the text in the element when focusing.
Expand All @@ -88,7 +104,7 @@ Set `selectText` to `true` to select the text in the element when focusing.

### `focusKey` action

This utility is also available as a [Svelte action](https://svelte.dev/docs#use_action).
This utility also provides a [Svelte action](https://svelte.dev/docs#use_action).

```svelte
<script>
Expand All @@ -102,11 +118,13 @@ This utility is also available as a [Svelte action](https://svelte.dev/docs#use_

### Props

| Name | Description | Type | Default value |
| :--------- | :-------------------------------- | :------------ | :------------ |
| element | HTML element to focus | `HTMLElement` | `null` |
| key | Key to trigger focus when pressed | `string` | `"/"` |
| selectText | Select element text when focusing | `boolean` | `false` |
| Name | Description | Type | Default value |
| :--------- | :-------------------------------- | :--------------------- | :------------ |
| element | HTML element to focus | `HTMLElement` | `null` |
| key | Key to trigger focus when pressed | `string` or `string[]` | `"/"` |
| selectText | Select element text when focusing | `boolean` | `false` |

The `focusKey` action has the same props as `FocusKey` except for `element`.

## TypeScript

Expand Down
5 changes: 4 additions & 1 deletion src/FocusKey.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,22 @@
/**
* Specify the key to trigger the element focus
* @type {string | string[]}
*/
export let key = "/";
/**
* Set to `true` to select text in the element when focused
*/
export let selectText = false;
$: keys = Array.isArray(key) ? key : [key];
</script>

<svelte:body
on:keydown={(e) => {
if (
e.key === key &&
keys.some((key) => key === e.key) &&
element != null &&
document.activeElement.tagName === "BODY" &&
document.activeElement !== element
Expand Down
5 changes: 3 additions & 2 deletions src/focus-key.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
/**
* @param {HTMLElement} element
* @param {{ key?: string; selectText?: boolean; }} [options]
* @param {{ key?: string | string[]; selectText?: boolean; }} [options]
*/
export function focusKey(element, options = {}) {
const key = options.key || "/";
const keys = Array.isArray(key) ? key : [key]
const selectText = options.selectText === true;

const handleKeydown = (e) => {
if (
e.key === key &&
keys.some((key) => key === e.key) &&
element != null &&
document.activeElement.tagName === "BODY" &&
document.activeElement !== element
Expand Down
16 changes: 6 additions & 10 deletions test/FocusKey.test.svelte
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
<script lang="ts">
import FocusKey, { focusKey } from "../types";
import FocusKeyDirectImport from "../types/FocusKey.svelte";
import FocusKeyDirectImport, {
FocusKeyProps,
} from "../types/FocusKey.svelte";
let element: HTMLInputElement;
let key: FocusKeyProps["key"] = ["s"];
</script>

<input bind:this={element} />

<!-- svelte-ignore missing-declaration -->
<FocusKey {element} key="s" selectText />

<!-- svelte-ignore missing-declaration -->
<FocusKeyDirectImport {element} />

<input use:focusKey />

<input use:focusKey={{ key: "s", selectText: true }} />
<FocusKeyDirectImport {element} {key} />
<input use:focusKey={{ key: ["s"], selectText: true }} />
2 changes: 1 addition & 1 deletion types/FocusKey.svelte.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export interface FocusKeyProps {
* Specify the key to trigger the element focus
* @default "/"
*/
key?: string;
key?: string | string[];

/**
* Set to `true` to select text in the element when focused
Expand Down

0 comments on commit abe1960

Please sign in to comment.