Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

trap-focus-svelte

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

trap-focus-svelte - npm Package Compare versions

Comparing version 1.0.2 to 1.1.0-rc1

2

dist/trap-focus-svelte.svelte.js

@@ -1,1 +0,1 @@

let t=[];function e(t,e,n){return t.addEventListener(e,n),()=>t.removeEventListener(e,n)}function n(n,o=1){let c=0;const u=e(document,"keydown",(t=>c=t.shiftKey&&"Tab"==t.key));function r(){const t=[...n.querySelectorAll("*")].filter((t=>t.tabIndex>=0));return[t.at(0)??n,t.at(-1)??n]}let s;function f(){t.push(n),s=document.activeElement,r().at(0).focus()}function i(){t=t.filter((t=>t!=n)),s.focus()}o&&f();const a=e=>t.at(-1)?.contains(e),d=e(n,"focusout",(t=>{if(a(n)){const[e,n]=r();t.target==e&&c?n.focus():t.target!=n||c||e.focus()}})),l=e(document,"focusin",(t=>{if(a(n)&&!a(t.target)){const[t,e]=r();(c?e:t).focus()}}));return{update(t){t?f():i()},destroy(){u(),l(),d(),i()}}}export{n as trapFocus};
let t=[];function e(e,n=1){function o(){const t=[...e.querySelectorAll("*")].filter((t=>t.tabIndex>=0));return[t.at(0)??e,t.at(-1)??e]}let c;function u(){t.push(e),c=document.activeElement,o().at(0).focus()}function r(){t.pop(),c.focus()}n&&u();const s=e=>t.at(-1)?.contains(e),a=((f=document).addEventListener("focusin",i=t=>{if(!s(e)||s(t.target))return;const[n,c]=o(),u=t.relatedTarget;u&&s(u)&&u!==c?u!==n&&u!==e?u.focus():c.focus():n.focus()}),()=>f.removeEventListener("focusin",i));var f,i;return{update(t){t?u():r()},destroy(){a(),r()}}}export{e as trapFocus};

@@ -11,13 +11,16 @@ let stack: HTMLElement[] = []

function trapFocus(wrap: HTMLElement, active = true) {
// true if tabbing backwards with shift + tab
let shiftTab = false
/** time when tab was last pressed */
// let tabTime: number
// /** true if shift key was pressed while tab was pressed */
// let shiftKey: boolean
// set shiftTab to true if shift + tab is pressed
const shiftTabListener = listen(
document,
'keydown',
(e: KeyboardEvent) => (shiftTab = e.shiftKey && e.key == 'Tab')
)
// /** sets tabTime and shiftKey */
// const shiftTabListener = listen(document, 'keydown', (e: KeyboardEvent) => {
// if (e.code == 'Tab') {
// shiftKey = e.shiftKey
// tabTime = e.timeStamp
// }
// })
// return the first and last focusable children
/** return the first and last focusable children */
function getFirstAndLastFocusable() {

@@ -41,3 +44,3 @@ const els = [...wrap.querySelectorAll('*')].filter(

function removeFromStack() {
stack = stack.filter((el) => el != wrap)
stack.pop()
lastActiveElement.focus()

@@ -54,21 +57,35 @@ }

/** loop focus if leaving first of last focusable element in wrap */
const focusOutListener = listen(wrap, 'focusout', (e: FocusEvent) => {
if (inCurrentTrap(wrap)) {
const [firstFocusableEl, lastFocusableEl] = getFirstAndLastFocusable()
if (e.target == firstFocusableEl && shiftTab) {
lastFocusableEl.focus()
} else if (e.target == lastFocusableEl && !shiftTab) {
firstFocusableEl.focus()
}
/** moves focus back to wrap if something outside the wrap is focused */
const focusOutListener = listen(document, 'focusin', (e: FocusEvent) => {
// return if ths trap is not active
// return if focus is inside the trap
if (!inCurrentTrap(wrap) || inCurrentTrap(e.target as HTMLElement)) {
return
}
})
const [firstFocusable, lastFocusable] = getFirstAndLastFocusable()
const previousFocusable = e.relatedTarget as HTMLElement
// const isTab = e.timeStamp - tabTime < 50
/** moves focus back to wrap if something outside the wrap is focused */
const focusListener = listen(document, 'focusin', (e: FocusEvent) => {
if (inCurrentTrap(wrap) && !inCurrentTrap(e.target as HTMLElement)) {
const [first, last] = getFirstAndLastFocusable()
let focusEl = shiftTab ? last : first
focusEl.focus()
// if no previousFocusable, focus first focusable
// if previousFocusable is not in the trap, focus first focusable
// if last element, focus first focusable
if (
!previousFocusable ||
!inCurrentTrap(previousFocusable) ||
previousFocusable === lastFocusable
) {
// console.log('last element and tab within time (but not shift tab) focus first element')
firstFocusable.focus()
return
}
// if first element and shift tab within time, focus last element
if (previousFocusable === firstFocusable || previousFocusable === wrap) {
// console.log('first element and shift tab within time, focus last element')
lastFocusable.focus()
return
}
// fall back to focus on previousFocusable (we made sure it was in current trap above)
// console.log('fall back to focus on relatedTarget')
previousFocusable.focus()
})

@@ -87,5 +104,5 @@

destroy() {
shiftTabListener()
focusListener()
// shiftTabListener()
focusOutListener()
// focusOutListener()
removeFromStack()

@@ -92,0 +109,0 @@ },

{
"name": "trap-focus-svelte",
"version": "1.0.2",
"version": "1.1.0-rc1",
"license": "MIT",

@@ -5,0 +5,0 @@ "description": "Small 0.4kB focus trap that supports stacking, toggling, and dynamic content. Compatible with any framework.",

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc