@humanspeak/svelte-motion
Version:
Framer Motion for Svelte 5. Declarative motion.<tag> components with AnimatePresence exit animations, gestures (hover, tap, drag, focus, in-view), variants, FLIP layout animations, shared-layout transitions, spring physics, and scroll-linked motion values
41 lines (40 loc) • 1.36 kB
JavaScript
/**
* Determines if an HTML element is natively focusable.
*
* Checks whether a given tag with provided attributes can receive keyboard
* focus without needing an explicit `tabindex`. Elements are considered
* natively focusable if they have `tabindex`, `tabIndex`, `contenteditable`,
* or are inherently focusable tags like `button`, `input`, or anchors with `href`.
*
* @param tag - The HTML element tag name.
* @param attrs - Attributes object that may contain focusability hints.
* @returns `true` if the element is natively focusable, otherwise `false`.
*
* @example
* ```typescript
* isNativelyFocusable('button', {}) // true
* isNativelyFocusable('div', { tabindex: '0' }) // true
* isNativelyFocusable('a', { href: '/home' }) // true
* isNativelyFocusable('div', {}) // false
* ```
*/
export const isNativelyFocusable = (tag, attrs = {}) => {
if (attrs.tabindex != null)
return true;
if (attrs.tabIndex != null)
return true;
if (attrs.contenteditable != null)
return true;
switch (tag) {
case 'a':
return Boolean(attrs.href);
case 'button':
case 'input':
case 'select':
case 'textarea':
case 'summary':
return true;
default:
return false;
}
};