@spectrum-web-components/reactive-controllers
Advanced tools
Comparing version 0.35.1-rc.43 to 0.36.0
{ | ||
"name": "@spectrum-web-components/reactive-controllers", | ||
"version": "0.35.1-rc.43+432051b80", | ||
"version": "0.36.0", | ||
"publishConfig": { | ||
@@ -82,3 +82,3 @@ "access": "public" | ||
], | ||
"gitHead": "432051b8085e7c86032333fa296bfa5334d47d84" | ||
"gitHead": "a532ff8a410abeefb54d9638a2316ae82570566e" | ||
} |
@@ -34,2 +34,3 @@ import type { ReactiveController, ReactiveElement } from 'lit'; | ||
constructor(host: ReactiveElement, { direction, elementEnterAction, elements, focusInIndex, isFocusableElement, listenerScope, }?: FocusGroupConfig<T>); | ||
handleItemMutation(): void; | ||
update({ elements }?: FocusGroupConfig<T>): void; | ||
@@ -36,0 +37,0 @@ focus(options?: FocusOptions): void; |
"use strict"; | ||
import { MutationController } from "@lit-labs/observers/mutation-controller.js"; | ||
function ensureMethod(value, type, fallback) { | ||
@@ -91,2 +92,11 @@ if (typeof value === type) { | ||
}; | ||
new MutationController(host, { | ||
config: { | ||
childList: true, | ||
subtree: true | ||
}, | ||
callback: () => { | ||
this.handleItemMutation(); | ||
} | ||
}); | ||
this.host = host; | ||
@@ -150,2 +160,20 @@ this.host.addController(this); | ||
} | ||
/* In handleItemMutation() method the first if condition is checking if the element is not focused or if the element's children's length is not decreasing then it means no element has been deleted and we must return. | ||
Then we are checking if the deleted element was the focused one before the deletion if so then we need to proceed else we casn return; | ||
*/ | ||
handleItemMutation() { | ||
if (this._currentIndex == -1 || this.elements.length <= this._elements().length) | ||
return; | ||
const focusedElement = this.elements[this.currentIndex]; | ||
this.clearElementCache(); | ||
if (this.elements.includes(focusedElement)) | ||
return; | ||
const moveToNextElement = this.currentIndex !== this.elements.length; | ||
const diff = moveToNextElement ? 1 : -1; | ||
if (moveToNextElement) { | ||
this.setCurrentIndexCircularly(-1); | ||
} | ||
this.setCurrentIndexCircularly(diff); | ||
this.focus(); | ||
} | ||
update({ elements } = { elements: () => [] }) { | ||
@@ -158,6 +186,9 @@ this.unmanage(); | ||
focus(options) { | ||
let focusElement = this.elements[this.currentIndex]; | ||
const elements = this.elements; | ||
if (!elements.length) | ||
return; | ||
let focusElement = elements[this.currentIndex]; | ||
if (!focusElement || !this.isFocusableElement(focusElement)) { | ||
this.setCurrentIndexCircularly(1); | ||
focusElement = this.elements[this.currentIndex]; | ||
focusElement = elements[this.currentIndex]; | ||
} | ||
@@ -194,3 +225,2 @@ if (focusElement && this.isFocusableElement(focusElement)) { | ||
this.host.removeEventListener("keydown", this.handleKeydown); | ||
this.currentIndex = this.focusInIndex; | ||
this.focused = false; | ||
@@ -197,0 +227,0 @@ } |
@@ -1,2 +0,2 @@ | ||
"use strict";function r(i,e,t){return typeof i===e?()=>i:typeof i=="function"?i:t}export class FocusGroupController{constructor(e,{direction:t,elementEnterAction:n,elements:s,focusInIndex:o,isFocusableElement:h,listenerScope:c}={elements:()=>[]}){this._currentIndex=-1;this._direction=()=>"both";this.directionLength=5;this.elementEnterAction=e=>{};this._focused=!1;this._focusInIndex=e=>0;this.isFocusableElement=e=>!0;this._listenerScope=()=>this.host;this.offset=0;this.handleFocusin=e=>{if(!this.isEventWithinListenerScope(e))return;this.isRelatedTargetAnElement(e)&&this.hostContainsFocus();const t=e.composedPath();let n=-1;t.find(s=>(n=this.elements.indexOf(s),n!==-1)),this.currentIndex=n>-1?n:this.currentIndex};this.handleFocusout=e=>{this.isRelatedTargetAnElement(e)&&this.hostNoLongerContainsFocus()};this.handleKeydown=e=>{if(!this.acceptsEventCode(e.code)||e.defaultPrevented)return;let t=0;switch(e.code){case"ArrowRight":t+=1;break;case"ArrowDown":t+=this.direction==="grid"?this.directionLength:1;break;case"ArrowLeft":t-=1;break;case"ArrowUp":t-=this.direction==="grid"?this.directionLength:1;break;case"End":this.currentIndex=0,t-=1;break;case"Home":this.currentIndex=this.elements.length-1,t+=1;break}e.preventDefault(),this.direction==="grid"&&this.currentIndex+t<0?this.currentIndex=0:this.direction==="grid"&&this.currentIndex+t>this.elements.length-1?this.currentIndex=this.elements.length-1:this.setCurrentIndexCircularly(t),this.elementEnterAction(this.elements[this.currentIndex]),this.focus()};this.host=e,this.host.addController(this),this._elements=s,this.isFocusableElement=h||this.isFocusableElement,this._direction=r(t,"string",this._direction),this.elementEnterAction=n||this.elementEnterAction,this._focusInIndex=r(o,"number",this._focusInIndex),this._listenerScope=r(c,"object",this._listenerScope)}get currentIndex(){return this._currentIndex===-1&&(this._currentIndex=this.focusInIndex),this._currentIndex-this.offset}set currentIndex(e){this._currentIndex=e+this.offset}get direction(){return this._direction()}get elements(){return this.cachedElements||(this.cachedElements=this._elements()),this.cachedElements}set focused(e){e!==this.focused&&(this._focused=e)}get focused(){return this._focused}get focusInElement(){return this.elements[this.focusInIndex]}get focusInIndex(){return this._focusInIndex(this.elements)}isEventWithinListenerScope(e){return this._listenerScope()===this.host?!0:e.composedPath().includes(this._listenerScope())}update({elements:e}={elements:()=>[]}){this.unmanage(),this._elements=e,this.clearElementCache(),this.manage()}focus(e){let t=this.elements[this.currentIndex];(!t||!this.isFocusableElement(t))&&(this.setCurrentIndexCircularly(1),t=this.elements[this.currentIndex]),t&&this.isFocusableElement(t)&&t.focus(e)}clearElementCache(e=0){delete this.cachedElements,this.offset=e}setCurrentIndexCircularly(e){const{length:t}=this.elements;let n=t,s=(t+this.currentIndex+e)%t;for(;n&&this.elements[s]&&!this.isFocusableElement(this.elements[s]);)s=(t+s+e)%t,n-=1;this.currentIndex=s}hostContainsFocus(){this.host.addEventListener("focusout",this.handleFocusout),this.host.addEventListener("keydown",this.handleKeydown),this.focused=!0}hostNoLongerContainsFocus(){this.host.addEventListener("focusin",this.handleFocusin),this.host.removeEventListener("focusout",this.handleFocusout),this.host.removeEventListener("keydown",this.handleKeydown),this.currentIndex=this.focusInIndex,this.focused=!1}isRelatedTargetAnElement(e){const t=e.relatedTarget;return!this.elements.includes(t)}acceptsEventCode(e){if(e==="End"||e==="Home")return!0;switch(this.direction){case"horizontal":return e==="ArrowLeft"||e==="ArrowRight";case"vertical":return e==="ArrowUp"||e==="ArrowDown";case"both":case"grid":return e.startsWith("Arrow")}}manage(){this.addEventListeners()}unmanage(){this.removeEventListeners()}addEventListeners(){this.host.addEventListener("focusin",this.handleFocusin)}removeEventListeners(){this.host.removeEventListener("focusin",this.handleFocusin),this.host.removeEventListener("focusout",this.handleFocusout),this.host.removeEventListener("keydown",this.handleKeydown)}hostConnected(){this.addEventListeners()}hostDisconnected(){this.removeEventListeners()}} | ||
"use strict";import{MutationController as l}from"@lit-labs/observers/mutation-controller.js";function r(i,e,t){return typeof i===e?()=>i:typeof i=="function"?i:t}export class FocusGroupController{constructor(e,{direction:t,elementEnterAction:n,elements:s,focusInIndex:o,isFocusableElement:h,listenerScope:c}={elements:()=>[]}){this._currentIndex=-1;this._direction=()=>"both";this.directionLength=5;this.elementEnterAction=e=>{};this._focused=!1;this._focusInIndex=e=>0;this.isFocusableElement=e=>!0;this._listenerScope=()=>this.host;this.offset=0;this.handleFocusin=e=>{if(!this.isEventWithinListenerScope(e))return;this.isRelatedTargetAnElement(e)&&this.hostContainsFocus();const t=e.composedPath();let n=-1;t.find(s=>(n=this.elements.indexOf(s),n!==-1)),this.currentIndex=n>-1?n:this.currentIndex};this.handleFocusout=e=>{this.isRelatedTargetAnElement(e)&&this.hostNoLongerContainsFocus()};this.handleKeydown=e=>{if(!this.acceptsEventCode(e.code)||e.defaultPrevented)return;let t=0;switch(e.code){case"ArrowRight":t+=1;break;case"ArrowDown":t+=this.direction==="grid"?this.directionLength:1;break;case"ArrowLeft":t-=1;break;case"ArrowUp":t-=this.direction==="grid"?this.directionLength:1;break;case"End":this.currentIndex=0,t-=1;break;case"Home":this.currentIndex=this.elements.length-1,t+=1;break}e.preventDefault(),this.direction==="grid"&&this.currentIndex+t<0?this.currentIndex=0:this.direction==="grid"&&this.currentIndex+t>this.elements.length-1?this.currentIndex=this.elements.length-1:this.setCurrentIndexCircularly(t),this.elementEnterAction(this.elements[this.currentIndex]),this.focus()};new l(e,{config:{childList:!0,subtree:!0},callback:()=>{this.handleItemMutation()}}),this.host=e,this.host.addController(this),this._elements=s,this.isFocusableElement=h||this.isFocusableElement,this._direction=r(t,"string",this._direction),this.elementEnterAction=n||this.elementEnterAction,this._focusInIndex=r(o,"number",this._focusInIndex),this._listenerScope=r(c,"object",this._listenerScope)}get currentIndex(){return this._currentIndex===-1&&(this._currentIndex=this.focusInIndex),this._currentIndex-this.offset}set currentIndex(e){this._currentIndex=e+this.offset}get direction(){return this._direction()}get elements(){return this.cachedElements||(this.cachedElements=this._elements()),this.cachedElements}set focused(e){e!==this.focused&&(this._focused=e)}get focused(){return this._focused}get focusInElement(){return this.elements[this.focusInIndex]}get focusInIndex(){return this._focusInIndex(this.elements)}isEventWithinListenerScope(e){return this._listenerScope()===this.host?!0:e.composedPath().includes(this._listenerScope())}handleItemMutation(){if(this._currentIndex==-1||this.elements.length<=this._elements().length)return;const e=this.elements[this.currentIndex];if(this.clearElementCache(),this.elements.includes(e))return;const t=this.currentIndex!==this.elements.length,n=t?1:-1;t&&this.setCurrentIndexCircularly(-1),this.setCurrentIndexCircularly(n),this.focus()}update({elements:e}={elements:()=>[]}){this.unmanage(),this._elements=e,this.clearElementCache(),this.manage()}focus(e){const t=this.elements;if(!t.length)return;let n=t[this.currentIndex];(!n||!this.isFocusableElement(n))&&(this.setCurrentIndexCircularly(1),n=t[this.currentIndex]),n&&this.isFocusableElement(n)&&n.focus(e)}clearElementCache(e=0){delete this.cachedElements,this.offset=e}setCurrentIndexCircularly(e){const{length:t}=this.elements;let n=t,s=(t+this.currentIndex+e)%t;for(;n&&this.elements[s]&&!this.isFocusableElement(this.elements[s]);)s=(t+s+e)%t,n-=1;this.currentIndex=s}hostContainsFocus(){this.host.addEventListener("focusout",this.handleFocusout),this.host.addEventListener("keydown",this.handleKeydown),this.focused=!0}hostNoLongerContainsFocus(){this.host.addEventListener("focusin",this.handleFocusin),this.host.removeEventListener("focusout",this.handleFocusout),this.host.removeEventListener("keydown",this.handleKeydown),this.focused=!1}isRelatedTargetAnElement(e){const t=e.relatedTarget;return!this.elements.includes(t)}acceptsEventCode(e){if(e==="End"||e==="Home")return!0;switch(this.direction){case"horizontal":return e==="ArrowLeft"||e==="ArrowRight";case"vertical":return e==="ArrowUp"||e==="ArrowDown";case"both":case"grid":return e.startsWith("Arrow")}}manage(){this.addEventListeners()}unmanage(){this.removeEventListeners()}addEventListeners(){this.host.addEventListener("focusin",this.handleFocusin)}removeEventListeners(){this.host.removeEventListener("focusin",this.handleFocusin),this.host.removeEventListener("focusout",this.handleFocusout),this.host.removeEventListener("keydown",this.handleKeydown)}hostConnected(){this.addEventListeners()}hostDisconnected(){this.removeEventListeners()}} | ||
//# sourceMappingURL=FocusGroup.js.map |
@@ -6,7 +6,7 @@ "use strict"; | ||
import { MatchMediaController } from "@spectrum-web-components/reactive-controllers/src/MatchMedia.js"; | ||
class TestEl extends LitElement { | ||
} | ||
customElements.define("test-match-media-el", TestEl); | ||
describe("Match Media", () => { | ||
it("responds to media changes", async () => { | ||
class TestEl extends LitElement { | ||
} | ||
customElements.define("test-match-media-el", TestEl); | ||
const el = await fixture( | ||
@@ -13,0 +13,0 @@ html` |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 4 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 4 instances in 1 package
179464
1161
0