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