focus: add selectAll helper, fix focus next behavior with selected text

This commit is contained in:
Elijah Duffy
2025-07-22 15:39:21 -07:00
parent d4935b6e7c
commit 2e3de49851

View File

@@ -1,3 +1,4 @@
import { tick } from 'svelte';
import type { Attachment } from 'svelte/attachments';
export type FocusKeymap = Record<string, 'next' | 'previous'>;
@@ -73,7 +74,8 @@ export class FocusManager {
});
}
/** Returns an attachment that adds a button element to the focus manager.
/**
* Returns an attachment that adds a button element to the focus manager.
*/
button(): Attachment<HTMLButtonElement> {
return (node) => {
@@ -107,7 +109,7 @@ export class FocusManager {
/**
* Returns an attachment that adds an input element to the focus manager.
*/
input(opts?: { keymap?: FocusKeymap }): Attachment<HTMLInputElement> {
input(opts?: { keymap?: FocusKeymap; selectAll?: boolean }): Attachment<HTMLInputElement> {
return (node) => {
this.add(node);
this.attachFocusHandlers(node);
@@ -126,6 +128,7 @@ export class FocusManager {
this.focusPrevious();
} else if (
(e.key === 'ArrowRight' || e.key === 'End') &&
target.selectionStart === target.selectionEnd &&
target.selectionEnd === target.value.length
) {
this.focusNext();
@@ -150,6 +153,13 @@ export class FocusManager {
e.preventDefault();
});
if (opts?.selectAll) {
node.addEventListener('focus', async () => {
await tick();
node.select();
});
}
return () => this.remove(node);
};
}