-
Notifications
You must be signed in to change notification settings - Fork 151
fix: highlight filename without extension #8204
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
| await tick(); | ||
| inputElement.focus(); | ||
| setTimeout(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to prevent the browser behaviour, needs a small timeout to wait for the browser to settle down
|
The changes to 1. Early Returns / Guard ClausesConvert nested onMount(async () => {
if (!claimFocusOnMount) return;
if (selectElement) {
selectElement.focus();
return;
}
if (!inputElement) return;
if (selectTextOnMount && inputElement instanceof HTMLInputElement) {
await applyTextSelection(inputElement);
} else {
inputElement.focus();
}
});2. Extract Helper FunctionsBreak out the complex selection logic: /**
* Applies focus and text selection to an input element.
* Uses a small delay to ensure browser completes focus before setting selection.
*/
async function applyTextSelection(element: HTMLInputElement) {
await tick();
element.focus();
const SELECTION_DELAY_MS = 10; // Browser needs time to complete focus
setTimeout(() => {
if (!(element instanceof HTMLInputElement)) return;
if (selectionStart !== undefined && selectionEnd !== undefined) {
element.setSelectionRange(selectionStart, selectionEnd);
} else {
element.select();
}
}, SELECTION_DELAY_MS);
}
onMount(async () => {
if (!claimFocusOnMount) return;
if (selectElement) {
selectElement.focus();
return;
}
if (!inputElement) return;
if (selectTextOnMount && inputElement instanceof HTMLInputElement) {
await applyTextSelection(inputElement);
} else {
inputElement.focus();
}
});3. Complete Refactored Version (Recommended)Here's a cleaner, more maintainable version: // Constants
const SELECTION_DELAY_MS = 10; // Browser needs time to complete focus state
// Helper functions
function isTextInput(element: HTMLElement | undefined): element is HTMLInputElement {
return element instanceof HTMLInputElement;
}
async function setTextSelection(
element: HTMLInputElement,
start: number | undefined,
end: number | undefined
) {
await tick();
element.focus();
setTimeout(() => {
if (start !== undefined && end !== undefined) {
element.setSelectionRange(start, end);
} else {
element.select();
}
}, SELECTION_DELAY_MS);
}
onMount(async () => {
if (!claimFocusOnMount) return;
// Priority 1: Select element (dropdowns)
if (selectElement) {
selectElement.focus();
return;
}
// Priority 2: Input element (text inputs)
if (!inputElement) return;
// Simple focus for non-text inputs or when selection not requested
if (!selectTextOnMount || !isTextInput(inputElement)) {
inputElement.focus();
return;
}
// Apply text selection for text inputs
await setTextSelection(inputElement, selectionStart, selectionEnd);
});Key Improvements✅ Reduced nesting: 1-2 levels max instead of 4-5 Bonus: Consider
|
| if (!isDir && fileName) { | ||
| const lastDotIndex = fileName.lastIndexOf("."); | ||
| if (lastDotIndex > 0) { | ||
| selectionStart = 0; | ||
| selectionEnd = lastDotIndex; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like duplicated code to what was added in InputWithConfirm.svelte. Mind factoring out?
| let selectionStart: number | undefined = undefined; | ||
| let selectionEnd: number | undefined = undefined; | ||
| $: if (type === "File" && value) { | ||
| const lastDotIndex = value.lastIndexOf("."); | ||
| if (lastDotIndex > 0) { | ||
| selectionStart = 0; | ||
| selectionEnd = lastDotIndex; | ||
| } else { | ||
| selectionStart = undefined; | ||
| selectionEnd = undefined; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is business logic that should live outside of this generic form component. Mind keeping this component domain-agnostic?
Opinionated nit: when editing a file name this will highlight just filename without extension so you can just type the new name without having to touch the mouse.
Checklist: