forked from spicetify/docs
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTabs.astro
More file actions
113 lines (92 loc) · 3.42 KB
/
Copy pathTabs.astro
File metadata and controls
113 lines (92 loc) · 3.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
---
interface Props {
groupId?: string;
}
const { groupId } = Astro.props;
---
<div class="tabs-container" data-tab-group={groupId || undefined}>
<div class="tab-list" role="tablist"></div>
<div class="tab-panels">
<slot />
</div>
</div>
<script>
function detectOS(): 'windows' | 'linux' | 'macos' {
const ua = navigator.userAgent.toLowerCase();
if (ua.includes('mac')) return 'macos';
if (ua.includes('linux')) return 'linux';
return 'windows';
}
function findOSTabIndex(
panels: NodeListOf<HTMLElement>,
os: 'windows' | 'linux' | 'macos',
): number {
const panelArray = Array.from(panels);
// Try exact OS match first
const exactMatch = panelArray.findIndex((p) => {
const value = (p.dataset.tabValue || '').toLowerCase();
const label = (p.dataset.tabLabel || '').toLowerCase();
if (os === 'windows') return value.includes('windows') || label.includes('windows');
if (os === 'macos') return value.includes('macos') || value.includes('mac') || label.includes('macos');
return value.includes('linux') || label.includes('linux');
});
if (exactMatch !== -1) return exactMatch;
// For macOS/Linux, fall back to combined "Linux / macOS" tabs
if (os === 'macos' || os === 'linux') {
const combined = panelArray.findIndex((p) => {
const value = (p.dataset.tabValue || '').toLowerCase();
const label = (p.dataset.tabLabel || '').toLowerCase();
return (value.includes('linux') && value.includes('mac')) ||
(label.includes('linux') && label.includes('mac'));
});
if (combined !== -1) return combined;
}
return -1;
}
function initTabs() {
const userOS = detectOS();
document.querySelectorAll('.tabs-container').forEach((container) => {
const el = container as HTMLElement;
const tabList = el.querySelector('.tab-list');
if (!tabList || tabList.children.length > 0) return;
const panels = el.querySelectorAll<HTMLElement>('.tab-panel');
if (panels.length === 0) return;
let defaultIndex = 0;
panels.forEach((panel, i) => {
const btn = document.createElement('button');
btn.textContent = panel.dataset.tabLabel || `Tab ${i + 1}`;
btn.role = 'tab';
btn.type = 'button';
btn.className = 'tab-button';
btn.dataset.tabValue = panel.dataset.tabValue || String(i);
if (panel.dataset.tabDefault !== undefined) {
defaultIndex = i;
}
tabList.appendChild(btn);
});
// Auto-select OS tab if this is an OS tab group
if (el.dataset.tabGroup === 'os') {
const osIndex = findOSTabIndex(panels, userOS);
if (osIndex !== -1) defaultIndex = osIndex;
}
const buttons = tabList.querySelectorAll<HTMLElement>('.tab-button');
buttons[defaultIndex]?.classList.add('active');
panels.forEach((panel, i) => {
panel.hidden = i !== defaultIndex;
});
tabList.addEventListener('click', (e) => {
const btn = (e.target as HTMLElement).closest<HTMLElement>(
'.tab-button',
);
if (!btn) return;
buttons.forEach((b) => b.classList.remove('active'));
btn.classList.add('active');
panels.forEach((p) => {
p.hidden = p.dataset.tabValue !== btn.dataset.tabValue;
});
});
});
}
initTabs();
document.addEventListener('astro:page-load', initTabs);
</script>