@@ -20,6 +20,12 @@ const classes = [
2020 even && styles .even ,
2121 className
2222]
23+
24+ const hasActive = items .some (item => item .active )
25+
26+ if (! hasActive ) {
27+ items [0 ].active = true
28+ }
2329---
2430
2531<section class:list ={ classes } data-id =" w-tabs" >
@@ -36,45 +42,70 @@ const classes = [
3642 ))}
3743 </div >
3844 </div >
39- <div class ={ styles .content } >
45+ <div
46+ class ={ styles .content }
47+ data-id =" w-tabs-content"
48+ data-active-index ={ items .findIndex (item => item .active )}
49+ >
4050 <slot />
4151 </div >
4252</section >
4353
4454<script >
45- import { on } from '../../utils/DOMUtils'
55+ import { get, on } from '../../utils/DOMUtils'
56+
57+ const setActiveTab = () => {
58+ const tabContents = get('[data-id="w-tabs-content"]', true) as NodeListOf<HTMLDivElement>
59+
60+ tabContents.forEach((tabContent) => {
61+ const contentChildren = Array.from(tabContent.children) as HTMLElement[]
62+
63+ if (!contentChildren.some(element => element.dataset.active === 'true')) {
64+ const index = Number(tabContent.dataset.activeIndex)
65+
66+ contentChildren[index].dataset.active = 'true'
67+ }
68+ })
69+ }
4670
4771 const addEventListeners = () => {
4872 on('[data-id="w-tabs"]', 'click', (event: Event) => {
49- const target = event.target as HTMLDivElement
73+ const target = event.target as HTMLButtonElement
74+
75+ if (!target.dataset.value) {
76+ return
77+ }
5078
51- if (target.dataset.value) {
52- const tabContent = target.parentElement
53- ?.parentElement
54- ?.nextElementSibling as HTMLDivElement
79+ const tabContent = target.parentElement
80+ ?.parentElement
81+ ?.nextElementSibling as HTMLDivElement
5582
56- Array.from(tabContent.children)
57- .forEach((element: any) => {
58- if (element.dataset.tab === target.dataset.value) {
59- element.dataset.active = true
60- } else {
61- element.dataset.active = false
62- }
63- })
83+ const btns = Array.from(target.parentElement?.querySelectorAll('button') as NodeListOf<HTMLButtonElement>)
84+ const clickedIndex = btns.indexOf(target)
85+ const contentChildren = Array.from(tabContent.children) as HTMLElement[]
86+ const hasExplicitTabs = contentChildren.some((element: HTMLElement) => element.dataset.tab)
6487
65- const tabs = target.parentElement?.querySelectorAll('button') as NodeListOf<HTMLButtonElement>
88+ btns.forEach((tab: HTMLElement, index: number) => {
89+ tab.dataset.active = index === clickedIndex ? 'true' : 'false'
6690
67- Array.from(tabs).forEach((tab: any) => {
68- tab.dataset.active = 'false'
91+ if (contentChildren[index]) {
92+ const content = contentChildren[index]
6993
70- if (tab.dataset.value === target.dataset.value) {
71- tab.dataset.active = 'true'
94+ if (hasExplicitTabs) {
95+ content.dataset.active = content.dataset.tab === target.dataset.value ? 'true' : 'false'
96+ } else {
97+ content.dataset.active = index === clickedIndex ? 'true' : 'false'
7298 }
73- })
74- }
99+ }
100+ })
75101 }, true)
76102 }
77103
78- on(document, 'astro:after-swap', addEventListeners)
79- addEventListeners()
104+ const initTabs = () => {
105+ setActiveTab()
106+ addEventListeners()
107+ }
108+
109+ on(document, 'astro:after-swap', initTabs)
110+ initTabs()
80111</script >
0 commit comments