Skip to content

Commit 3cb5d68

Browse files
committed
add TabContainerChange event class
1 parent aa116c9 commit 3cb5d68

2 files changed

Lines changed: 96 additions & 7 deletions

File tree

src/tab-container-element.ts

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,30 @@ function getTabs(el: TabContainerElement): HTMLElement[] {
77
)
88
}
99

10+
export class TabContainerChangeEvent extends Event {
11+
constructor(type: string, {tab, panel, ...init}: EventInit & {tab?: Element; panel?: Element}) {
12+
super(type, init)
13+
this.#tab = tab || null
14+
this.#panel = panel || null
15+
}
16+
17+
get detail() {
18+
// eslint-disable-next-line no-console
19+
console.warn('TabContainerElement.detail is deprecated, please use .panel instead')
20+
return {relatedTarget: this.#panel}
21+
}
22+
23+
#panel: Element | null = null
24+
get panel(): Element | null {
25+
return this.#panel
26+
}
27+
28+
#tab: Element | null = null
29+
get tab(): Element | null {
30+
return this.#tab
31+
}
32+
}
33+
1034
function getNavigationKeyCodes(vertical: boolean): [IncrementKeyCode[], DecrementKeyCode[]] {
1135
if (vertical) {
1236
return [
@@ -24,6 +48,42 @@ export class TabContainerElement extends HTMLElement {
2448
return this
2549
}
2650

51+
#onTabContainerChange: ((event: TabContainerChangeEvent) => void) | null = null
52+
get onTabContainerChange() {
53+
return this.#onTabContainerChange
54+
}
55+
56+
set onTabContainerChange(listener: ((event: TabContainerChangeEvent) => void) | null) {
57+
if (this.#onTabContainerChange) {
58+
this.removeEventListener(
59+
'tab-container-change',
60+
this.#onTabContainerChange as unknown as EventListenerOrEventListenerObject,
61+
)
62+
}
63+
this.#onTabContainerChange = typeof listener === 'object' || typeof listener === 'function' ? listener : null
64+
if (typeof listener === 'function') {
65+
this.addEventListener('tab-container-change', listener as unknown as EventListenerOrEventListenerObject)
66+
}
67+
}
68+
69+
#onTabContainerChanged: ((event: TabContainerChangeEvent) => void) | null = null
70+
get onTabContainerChanged() {
71+
return this.#onTabContainerChanged
72+
}
73+
74+
set onTabContainerChanged(listener: ((event: TabContainerChangeEvent) => void) | null) {
75+
if (this.#onTabContainerChanged) {
76+
this.removeEventListener(
77+
'tab-container-changed',
78+
this.#onTabContainerChanged as unknown as EventListenerOrEventListenerObject,
79+
)
80+
}
81+
this.#onTabContainerChanged = typeof listener === 'object' || typeof listener === 'function' ? listener : null
82+
if (typeof listener === 'function') {
83+
this.addEventListener('tab-container-changed', listener as unknown as EventListenerOrEventListenerObject)
84+
}
85+
}
86+
2787
connectedCallback(): void {
2888
this.addEventListener('keydown', (event: KeyboardEvent) => {
2989
const target = event.target
@@ -99,10 +159,11 @@ export class TabContainerElement extends HTMLElement {
99159
const selectedPanel = panels[index]
100160

101161
const cancelled = !this.dispatchEvent(
102-
new CustomEvent('tab-container-change', {
162+
new TabContainerChangeEvent('tab-container-change', {
103163
bubbles: true,
104164
cancelable: true,
105-
detail: {relatedTarget: selectedPanel},
165+
tab: selectedTab,
166+
panel: selectedPanel,
106167
}),
107168
)
108169
if (cancelled) return
@@ -124,9 +185,10 @@ export class TabContainerElement extends HTMLElement {
124185
selectedPanel.hidden = false
125186

126187
this.dispatchEvent(
127-
new CustomEvent('tab-container-changed', {
188+
new TabContainerChangeEvent('tab-container-changed', {
128189
bubbles: true,
129-
detail: {relatedTarget: selectedPanel},
190+
tab: selectedTab,
191+
panel: selectedPanel,
130192
}),
131193
)
132194
}

test/test.js

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,30 @@ describe('tab-container', function () {
1414
})
1515
})
1616

17+
describe('events', function () {
18+
it('has an onTabContainerChange property for the change event', function () {
19+
const el = document.createElement('tab-container')
20+
let called = false
21+
const listener = () => (called = true)
22+
el.onTabContainerChange = listener
23+
assert.equal(el.onTabContainerChange, listener)
24+
assert.equal(called, false)
25+
el.dispatchEvent(new Event('tab-container-change'))
26+
assert.equal(called, true)
27+
})
28+
29+
it('has an onTabContainerChanged property for the changed event', function () {
30+
const el = document.createElement('tab-container')
31+
let called = false
32+
const listener = () => (called = true)
33+
el.onTabContainerChanged = listener
34+
assert.equal(el.onTabContainerChanged, listener)
35+
assert.equal(called, false)
36+
el.dispatchEvent(new Event('tab-container-changed'))
37+
assert.equal(called, true)
38+
})
39+
})
40+
1741
describe('after tree insertion', function () {
1842
beforeEach(function () {
1943
document.body.innerHTML = `
@@ -54,7 +78,8 @@ describe('tab-container', function () {
5478
let counter = 0
5579
tabContainer.addEventListener('tab-container-changed', event => {
5680
counter++
57-
assert.equal(event.detail.relatedTarget, panels[1])
81+
assert.equal(event.tab, tabs[1])
82+
assert.equal(event.panel, panels[1])
5883
})
5984

6085
tabs[1].click()
@@ -112,7 +137,8 @@ describe('tab-container', function () {
112137
let counter = 0
113138
tabContainer.addEventListener('tab-container-change', event => {
114139
counter++
115-
assert.equal(event.detail.relatedTarget, panels[1])
140+
assert.equal(event.tab, tabs[1])
141+
assert.equal(event.panel, panels[1])
116142
event.preventDefault()
117143
})
118144

@@ -167,7 +193,8 @@ describe('tab-container', function () {
167193
let counter = 0
168194
tabContainer.addEventListener('tab-container-changed', event => {
169195
counter++
170-
assert.equal(event.detail.relatedTarget, panels[1])
196+
assert.equal(event.tab, tabs[1])
197+
assert.equal(event.panel, panels[1])
171198
})
172199

173200
tabContainer.selectTab(1)

0 commit comments

Comments
 (0)