From bca7aec1259216b2cc0c5cd47d9528e7b55313e5 Mon Sep 17 00:00:00 2001 From: Owen Niblock Date: Mon, 11 Mar 2024 19:07:00 +0000 Subject: [PATCH 1/4] Add tab index to event object --- custom-elements.json | 22 ++++++++++++++++++++++ src/tab-container-element.ts | 13 ++++++++++++- test/test.js | 7 ++++++- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/custom-elements.json b/custom-elements.json index bb7e766..fe0601c 100644 --- a/custom-elements.json +++ b/custom-elements.json @@ -117,6 +117,11 @@ "name": "detail", "readonly": true }, + { + "kind": "field", + "name": "tabIndex", + "readonly": true + }, { "kind": "field", "name": "panel", @@ -317,6 +322,23 @@ "name": "detail", "readonly": true }, + { + "kind": "field", + "name": "#tabIndex", + "privacy": "private", + "type": { + "text": "number | null" + }, + "default": "null" + }, + { + "kind": "field", + "name": "tabIndex", + "type": { + "text": "number | null" + }, + "readonly": true + }, { "kind": "field", "name": "#panel", diff --git a/src/tab-container-element.ts b/src/tab-container-element.ts index c01164d..831409d 100644 --- a/src/tab-container-element.ts +++ b/src/tab-container-element.ts @@ -2,9 +2,13 @@ const HTMLElement = globalThis.HTMLElement || (null as unknown as (typeof window const manualSlotsSupported = 'assign' in (globalThis.HTMLSlotElement?.prototype || {}) export class TabContainerChangeEvent extends Event { - constructor(type: string, {tab, panel, ...init}: EventInit & {tab?: Element; panel?: Element}) { + constructor( + type: string, + {tabIndex, tab, panel, ...init}: EventInit & {tabIndex?: number; tab?: Element; panel?: Element}, + ) { super(type, init) this.#tab = tab || null + this.#tabIndex = tabIndex || null this.#panel = panel || null } @@ -14,6 +18,11 @@ export class TabContainerChangeEvent extends Event { return {relatedTarget: this.#panel} } + #tabIndex: number | null = null + get tabIndex(): number | null { + return this.#tabIndex + } + #panel: Element | null = null get panel(): Element | null { return this.#panel @@ -341,6 +350,7 @@ export class TabContainerElement extends HTMLElement { if (this.#setupComplete) { const cancelled = !this.dispatchEvent( new TabContainerChangeEvent('tab-container-change', { + tabIndex: index, bubbles: true, cancelable: true, tab: selectedTab, @@ -376,6 +386,7 @@ export class TabContainerElement extends HTMLElement { selectedTab.focus() this.dispatchEvent( new TabContainerChangeEvent('tab-container-changed', { + tabIndex: index, bubbles: true, tab: selectedTab, panel: selectedPanel, diff --git a/test/test.js b/test/test.js index eb0c08f..441aa41 100644 --- a/test/test.js +++ b/test/test.js @@ -186,7 +186,7 @@ describe('tab-container', function () { expect(document.body).to.be.accessible() }) - it('click works and `tab-container-changed` event is dispatched', function () { + it('click works and `tab-container-changed` event is dispatched with correct index', function () { tabs[1].click() assert.deepStrictEqual(tabs.map(isSelected), [false, true, false], 'Second tab is selected') assert.deepStrictEqual(panels.map(isHidden), [true, false, true], 'Second panel is visible') @@ -201,6 +201,11 @@ describe('tab-container', function () { [tabs[1], tabs[1]], 'change events point to second tab', ) + assert.deepStrictEqual( + events.map(e => e.tabIndex), + [1, 1], + 'change events point to second tabIndex', + ) assert.deepStrictEqual( events.map(e => e.panel), [panels[1], panels[1]], From becda143f905eb48cfdd312340d86a3acec26d73 Mon Sep 17 00:00:00 2001 From: Owen Niblock Date: Mon, 11 Mar 2024 19:27:54 +0000 Subject: [PATCH 2/4] Update README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 426d338..f5b20ad 100644 --- a/README.md +++ b/README.md @@ -44,8 +44,8 @@ If none of the tabs have `aria-selected=true`, then the first tab will be select ### Events -- `tab-container-change` (bubbles, cancelable): fired on `` before a new tab is selected and visibility is updated. `event.tab` is the tab that will be focused and `tab.panel` is the panel that will be shown if the event isn't cancelled. -- `tab-container-changed` (bubbles): fired on `` after a new tab is selected and visibility is updated. `event.tab` is the tab that is now active (and will be focused right after this event) and `event.panel` is the newly visible tab panel. +- `tab-container-change` (bubbles, cancelable): fired on `` before a new tab is selected and visibility is updated. `event.tab` is the tab that will be focused, `event.tabIndex` is the 0-based index of the `tab` and `tab.panel` is the panel that will be shown if the event isn't cancelled. +- `tab-container-changed` (bubbles): fired on `` after a new tab is selected and visibility is updated. `event.tab` is the tab that is now active (and will be focused right after this event), `event.tabIndex` is the 0-based index of the `tab` and `event.panel` is the newly visible tab panel. ### Parts From 75d656a84b6ad7b7d9a8bd8e6a252c39702abaf3 Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Tue, 12 Mar 2024 18:58:08 +0100 Subject: [PATCH 3/4] Register event types for better type inference This allows typescript to know which kind of event object is passed to listeners for those event names. --- src/tab-container-element-define.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/tab-container-element-define.ts b/src/tab-container-element-define.ts index 208ac57..95f1baa 100644 --- a/src/tab-container-element-define.ts +++ b/src/tab-container-element-define.ts @@ -27,6 +27,14 @@ declare global { ['tab-container']: JSXBase['span'] & Partial> } } + interface GlobalEventHandlersEventMap { + 'tab-container-change': TabContainerChangeEvent; + 'tab-container-changed': TabContainerChangeEvent; + } + interface ElementEventMap { + 'tab-container-change': TabContainerChangeEvent; + 'tab-container-changed': TabContainerChangeEvent; + } } export default TabContainerElement From 21f1e2b8dcc43d7905dbe806e508ea6e510e0d9e Mon Sep 17 00:00:00 2001 From: Cameron Dutro Date: Tue, 12 Mar 2024 15:53:11 -0700 Subject: [PATCH 4/4] Fix linting issues --- src/tab-container-element-define.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tab-container-element-define.ts b/src/tab-container-element-define.ts index 95f1baa..ab9c4e3 100644 --- a/src/tab-container-element-define.ts +++ b/src/tab-container-element-define.ts @@ -1,4 +1,4 @@ -import {TabContainerElement} from './tab-container-element.js' +import {TabContainerChangeEvent, TabContainerElement} from './tab-container-element.js' const root = (typeof globalThis !== 'undefined' ? globalThis : window) as typeof window try { @@ -28,12 +28,12 @@ declare global { } } interface GlobalEventHandlersEventMap { - 'tab-container-change': TabContainerChangeEvent; - 'tab-container-changed': TabContainerChangeEvent; + 'tab-container-change': TabContainerChangeEvent + 'tab-container-changed': TabContainerChangeEvent } interface ElementEventMap { - 'tab-container-change': TabContainerChangeEvent; - 'tab-container-changed': TabContainerChangeEvent; + 'tab-container-change': TabContainerChangeEvent + 'tab-container-changed': TabContainerChangeEvent } } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy