@internetarchive/ia-topnav 1.3.28-alpha5 → 1.3.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -51,6 +51,13 @@ export default class KeyboardNavigation {
51
51
  * @param {KeyboardEvent} event - The keyboard event object.
52
52
  */
53
53
  handleKeyDown(event) {
54
+ const target = event.composedPath()[0];
55
+ // Ignore events from editable fields
56
+ if (target instanceof HTMLInputElement ||
57
+ target instanceof HTMLTextAreaElement ||
58
+ target.isContentEditable) {
59
+ return;
60
+ }
54
61
  const { key } = event;
55
62
  const isArrowKey = [
56
63
  'ArrowDown',
@@ -1 +1 @@
1
- {"version":3,"file":"keyboard-navigation.js","sourceRoot":"","sources":["../../../src/lib/keyboard-navigation.ts"],"names":[],"mappings":"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","sourcesContent":["export default class KeyboardNavigation {\n elementsContainer: HTMLElement;\n menuOption: string;\n focusableElements: HTMLElement[];\n focusedIndex: number;\n\n /**\n * Constructor for the KeyboardNavigation class.\n * @param {HTMLElement} elementsContainer - The container element that holds the focusable elements.\n * @param {string} menuOption - The type of menu option ('web' or 'usermenu').\n */\n constructor(elementsContainer: HTMLElement, menuOption: string) {\n this.elementsContainer = elementsContainer;\n this.menuOption = menuOption;\n this.focusableElements = this.getFocusableElements();\n this.focusedIndex = 0; // always start from first element\n\n if (menuOption !== 'search') {\n this.focusableElements[this.focusedIndex]?.focus();\n }\n this.handleKeyDown = this.handleKeyDown.bind(this);\n }\n\n /**\n * Gets an array of focusable elements within the container.\n * @returns {HTMLElement[]} An array of focusable elements.\n */\n getFocusableElements(): HTMLElement[] {\n const focusableTagSelectors = 'a[href], button, input, [tabindex]';\n\n const isFocusable = (el: Element) =>\n !el.hasAttribute('disabled') &&\n el.getAttribute('aria-hidden') !== 'true' &&\n el.getAttribute('tabindex') !== '-1';\n\n let elements;\n if (this.menuOption === 'web') {\n // wayback focusable elements\n const waybackSlider =\n this.elementsContainer.querySelector('wayback-slider')?.shadowRoot;\n const waybackSearch = waybackSlider?.querySelector('wayback-search');\n const waybackSearchElements = Array.from(\n waybackSearch?.shadowRoot?.querySelectorAll(focusableTagSelectors) ??\n [],\n );\n\n const normalElements = Array.from(\n waybackSlider?.querySelectorAll(focusableTagSelectors) ?? [],\n );\n\n // wayback save-form focusable elements\n const savePageForm = waybackSlider?.querySelector('save-page-form');\n const savePageFormElements = Array.from(\n savePageForm?.shadowRoot?.querySelectorAll(focusableTagSelectors) ?? [],\n );\n\n elements = [\n ...waybackSearchElements,\n ...normalElements,\n ...savePageFormElements,\n ];\n } else {\n elements = this.elementsContainer.querySelectorAll(focusableTagSelectors);\n }\n\n return Array.from(elements ?? []).filter(isFocusable) as HTMLElement[];\n }\n\n /**\n * Handles keyboard events and focuses the appropriate element.\n * @param {KeyboardEvent} event - The keyboard event object.\n */\n handleKeyDown(event: KeyboardEvent) {\n const { key } = event;\n const isArrowKey = [\n 'ArrowDown',\n 'ArrowRight',\n 'ArrowUp',\n 'ArrowLeft',\n ].includes(key);\n const isTabKey = key === 'Tab';\n\n if (isArrowKey) {\n this.handleArrowKey(key);\n event.preventDefault();\n } else if (isTabKey) {\n this.handleTabKey(event);\n }\n }\n\n /**\n * Handles arrow key events and focuses the next or previous element for topnav sub-nav and usermenu\n * @param {string} key - The key that was pressed ('ArrowDown', 'ArrowRight', 'ArrowUp', or 'ArrowLeft').\n */\n handleArrowKey(key: string) {\n const isDownOrRight = ['ArrowDown', 'ArrowRight'].includes(key);\n if (isDownOrRight) {\n this.focusNext();\n } else {\n this.focusPrevious();\n }\n }\n\n /**\n * Handles the Tab key event and focuses the next or previous menu item.\n * @param {KeyboardEvent} event - The keyboard event object.\n */\n handleTabKey(event: KeyboardEvent) {\n const isShiftPressed = event.shiftKey;\n\n this.emitFocusToOtherMenuItems(isShiftPressed);\n\n this.focusableElements[this.focusedIndex]?.blur();\n if (!['search'].includes(this.menuOption)) {\n event.preventDefault();\n }\n }\n\n /**\n * Focuses the previous focusable element in the container.\n */\n focusPrevious() {\n if (this.focusableElements.length === 0) return;\n this.focusedIndex =\n (this.focusedIndex - 1 + this.focusableElements.length) %\n this.focusableElements.length;\n this.focusableElements[this.focusedIndex]?.focus();\n }\n\n /**\n * Focuses the next focusable element in the container.\n */\n focusNext() {\n if (this.focusableElements.length === 0) return;\n this.focusedIndex = (this.focusedIndex + 1) % this.focusableElements.length;\n this.focusableElements[this.focusedIndex]?.focus();\n }\n\n /**\n * Focuses the other parent menu items based on the provided flag.\n * @param {boolean} isPrevious - A flag indicating whether to focus the previous menu item.\n */\n emitFocusToOtherMenuItems(isPrevious: boolean = false) {\n this.elementsContainer.dispatchEvent(\n new CustomEvent('focusToOtherMenuItem', {\n bubbles: true,\n composed: true,\n detail: {\n mediatype: this.menuOption,\n moveTo: isPrevious ? 'prev' : 'next',\n },\n }),\n );\n }\n}\n"]}
1
+ {"version":3,"file":"keyboard-navigation.js","sourceRoot":"","sources":["../../../src/lib/keyboard-navigation.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,OAAO,kBAAkB;IAMrC;;;;OAIG;IACH,YAAY,iBAA8B,EAAE,UAAkB;;QAC5D,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;QAC3C,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;QACrD,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,kCAAkC;QAEzD,IAAI,UAAU,KAAK,QAAQ,EAAE,CAAC;YAC5B,MAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC,0CAAE,KAAK,EAAE,CAAC;QACrD,CAAC;QACD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrD,CAAC;IAED;;;OAGG;IACH,oBAAoB;;QAClB,MAAM,qBAAqB,GAAG,oCAAoC,CAAC;QAEnE,MAAM,WAAW,GAAG,CAAC,EAAW,EAAE,EAAE,CAClC,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC;YAC5B,EAAE,CAAC,YAAY,CAAC,aAAa,CAAC,KAAK,MAAM;YACzC,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;QAEvC,IAAI,QAAQ,CAAC;QACb,IAAI,IAAI,CAAC,UAAU,KAAK,KAAK,EAAE,CAAC;YAC9B,6BAA6B;YAC7B,MAAM,aAAa,GACjB,MAAA,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,gBAAgB,CAAC,0CAAE,UAAU,CAAC;YACrE,MAAM,aAAa,GAAG,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;YACrE,MAAM,qBAAqB,GAAG,KAAK,CAAC,IAAI,CACtC,MAAA,MAAA,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,UAAU,0CAAE,gBAAgB,CAAC,qBAAqB,CAAC,mCAChE,EAAE,CACL,CAAC;YAEF,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,CAC/B,MAAA,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,gBAAgB,CAAC,qBAAqB,CAAC,mCAAI,EAAE,CAC7D,CAAC;YAEF,uCAAuC;YACvC,MAAM,YAAY,GAAG,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;YACpE,MAAM,oBAAoB,GAAG,KAAK,CAAC,IAAI,CACrC,MAAA,MAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,UAAU,0CAAE,gBAAgB,CAAC,qBAAqB,CAAC,mCAAI,EAAE,CACxE,CAAC;YAEF,QAAQ,GAAG;gBACT,GAAG,qBAAqB;gBACxB,GAAG,cAAc;gBACjB,GAAG,oBAAoB;aACxB,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,CAAC;QAC5E,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,EAAE,CAAC,CAAC,MAAM,CAAC,WAAW,CAAkB,CAAC;IACzE,CAAC;IAED;;;OAGG;IACH,aAAa,CAAC,KAAoB;QAChC,MAAM,MAAM,GAAG,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,CAAgB,CAAC;QAEtD,qCAAqC;QACrC,IACE,MAAM,YAAY,gBAAgB;YAClC,MAAM,YAAY,mBAAmB;YACrC,MAAM,CAAC,iBAAiB,EACxB,CAAC;YACD,OAAO;QACT,CAAC;QAED,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;QACtB,MAAM,UAAU,GAAG;YACjB,WAAW;YACX,YAAY;YACZ,SAAS;YACT,WAAW;SACZ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAChB,MAAM,QAAQ,GAAG,GAAG,KAAK,KAAK,CAAC;QAE/B,IAAI,UAAU,EAAE,CAAC;YACf,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;YACzB,KAAK,CAAC,cAAc,EAAE,CAAC;QACzB,CAAC;aAAM,IAAI,QAAQ,EAAE,CAAC;YACpB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,cAAc,CAAC,GAAW;QACxB,MAAM,aAAa,GAAG,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAChE,IAAI,aAAa,EAAE,CAAC;YAClB,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,YAAY,CAAC,KAAoB;;QAC/B,MAAM,cAAc,GAAG,KAAK,CAAC,QAAQ,CAAC;QAEtC,IAAI,CAAC,yBAAyB,CAAC,cAAc,CAAC,CAAC;QAE/C,MAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC,0CAAE,IAAI,EAAE,CAAC;QAClD,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YAC1C,KAAK,CAAC,cAAc,EAAE,CAAC;QACzB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,aAAa;;QACX,IAAI,IAAI,CAAC,iBAAiB,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAChD,IAAI,CAAC,YAAY;YACf,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC;gBACvD,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC;QAChC,MAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC,0CAAE,KAAK,EAAE,CAAC;IACrD,CAAC;IAED;;OAEG;IACH,SAAS;;QACP,IAAI,IAAI,CAAC,iBAAiB,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAChD,IAAI,CAAC,YAAY,GAAG,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC;QAC5E,MAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC,0CAAE,KAAK,EAAE,CAAC;IACrD,CAAC;IAED;;;OAGG;IACH,yBAAyB,CAAC,aAAsB,KAAK;QACnD,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAClC,IAAI,WAAW,CAAC,sBAAsB,EAAE;YACtC,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE;gBACN,SAAS,EAAE,IAAI,CAAC,UAAU;gBAC1B,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;aACrC;SACF,CAAC,CACH,CAAC;IACJ,CAAC;CACF","sourcesContent":["export default class KeyboardNavigation {\n elementsContainer: HTMLElement;\n menuOption: string;\n focusableElements: HTMLElement[];\n focusedIndex: number;\n\n /**\n * Constructor for the KeyboardNavigation class.\n * @param {HTMLElement} elementsContainer - The container element that holds the focusable elements.\n * @param {string} menuOption - The type of menu option ('web' or 'usermenu').\n */\n constructor(elementsContainer: HTMLElement, menuOption: string) {\n this.elementsContainer = elementsContainer;\n this.menuOption = menuOption;\n this.focusableElements = this.getFocusableElements();\n this.focusedIndex = 0; // always start from first element\n\n if (menuOption !== 'search') {\n this.focusableElements[this.focusedIndex]?.focus();\n }\n this.handleKeyDown = this.handleKeyDown.bind(this);\n }\n\n /**\n * Gets an array of focusable elements within the container.\n * @returns {HTMLElement[]} An array of focusable elements.\n */\n getFocusableElements(): HTMLElement[] {\n const focusableTagSelectors = 'a[href], button, input, [tabindex]';\n\n const isFocusable = (el: Element) =>\n !el.hasAttribute('disabled') &&\n el.getAttribute('aria-hidden') !== 'true' &&\n el.getAttribute('tabindex') !== '-1';\n\n let elements;\n if (this.menuOption === 'web') {\n // wayback focusable elements\n const waybackSlider =\n this.elementsContainer.querySelector('wayback-slider')?.shadowRoot;\n const waybackSearch = waybackSlider?.querySelector('wayback-search');\n const waybackSearchElements = Array.from(\n waybackSearch?.shadowRoot?.querySelectorAll(focusableTagSelectors) ??\n [],\n );\n\n const normalElements = Array.from(\n waybackSlider?.querySelectorAll(focusableTagSelectors) ?? [],\n );\n\n // wayback save-form focusable elements\n const savePageForm = waybackSlider?.querySelector('save-page-form');\n const savePageFormElements = Array.from(\n savePageForm?.shadowRoot?.querySelectorAll(focusableTagSelectors) ?? [],\n );\n\n elements = [\n ...waybackSearchElements,\n ...normalElements,\n ...savePageFormElements,\n ];\n } else {\n elements = this.elementsContainer.querySelectorAll(focusableTagSelectors);\n }\n\n return Array.from(elements ?? []).filter(isFocusable) as HTMLElement[];\n }\n\n /**\n * Handles keyboard events and focuses the appropriate element.\n * @param {KeyboardEvent} event - The keyboard event object.\n */\n handleKeyDown(event: KeyboardEvent) {\n const target = event.composedPath()[0] as HTMLElement;\n\n // Ignore events from editable fields\n if (\n target instanceof HTMLInputElement ||\n target instanceof HTMLTextAreaElement ||\n target.isContentEditable\n ) {\n return;\n }\n\n const { key } = event;\n const isArrowKey = [\n 'ArrowDown',\n 'ArrowRight',\n 'ArrowUp',\n 'ArrowLeft',\n ].includes(key);\n const isTabKey = key === 'Tab';\n\n if (isArrowKey) {\n this.handleArrowKey(key);\n event.preventDefault();\n } else if (isTabKey) {\n this.handleTabKey(event);\n }\n }\n\n /**\n * Handles arrow key events and focuses the next or previous element for topnav sub-nav and usermenu\n * @param {string} key - The key that was pressed ('ArrowDown', 'ArrowRight', 'ArrowUp', or 'ArrowLeft').\n */\n handleArrowKey(key: string) {\n const isDownOrRight = ['ArrowDown', 'ArrowRight'].includes(key);\n if (isDownOrRight) {\n this.focusNext();\n } else {\n this.focusPrevious();\n }\n }\n\n /**\n * Handles the Tab key event and focuses the next or previous menu item.\n * @param {KeyboardEvent} event - The keyboard event object.\n */\n handleTabKey(event: KeyboardEvent) {\n const isShiftPressed = event.shiftKey;\n\n this.emitFocusToOtherMenuItems(isShiftPressed);\n\n this.focusableElements[this.focusedIndex]?.blur();\n if (!['search'].includes(this.menuOption)) {\n event.preventDefault();\n }\n }\n\n /**\n * Focuses the previous focusable element in the container.\n */\n focusPrevious() {\n if (this.focusableElements.length === 0) return;\n this.focusedIndex =\n (this.focusedIndex - 1 + this.focusableElements.length) %\n this.focusableElements.length;\n this.focusableElements[this.focusedIndex]?.focus();\n }\n\n /**\n * Focuses the next focusable element in the container.\n */\n focusNext() {\n if (this.focusableElements.length === 0) return;\n this.focusedIndex = (this.focusedIndex + 1) % this.focusableElements.length;\n this.focusableElements[this.focusedIndex]?.focus();\n }\n\n /**\n * Focuses the other parent menu items based on the provided flag.\n * @param {boolean} isPrevious - A flag indicating whether to focus the previous menu item.\n */\n emitFocusToOtherMenuItems(isPrevious: boolean = false) {\n this.elementsContainer.dispatchEvent(\n new CustomEvent('focusToOtherMenuItem', {\n bubbles: true,\n composed: true,\n detail: {\n mediatype: this.menuOption,\n moveTo: isPrevious ? 'prev' : 'next',\n },\n }),\n );\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@internetarchive/ia-topnav",
3
- "version": "1.3.28-alpha5",
3
+ "version": "1.3.29",
4
4
  "description": "Top nav for Internet Archive",
5
5
  "license": "AGPL-3.0-only",
6
6
  "main": "dist/index.js",
@@ -71,6 +71,17 @@ export default class KeyboardNavigation {
71
71
  * @param {KeyboardEvent} event - The keyboard event object.
72
72
  */
73
73
  handleKeyDown(event: KeyboardEvent) {
74
+ const target = event.composedPath()[0] as HTMLElement;
75
+
76
+ // Ignore events from editable fields
77
+ if (
78
+ target instanceof HTMLInputElement ||
79
+ target instanceof HTMLTextAreaElement ||
80
+ target.isContentEditable
81
+ ) {
82
+ return;
83
+ }
84
+
74
85
  const { key } = event;
75
86
  const isArrowKey = [
76
87
  'ArrowDown',