Skip to content

Commit f55bf83

Browse files
committed
♿️ Improve Tabs component usability for mobile & overflow states
1 parent 689d430 commit f55bf83

File tree

6 files changed

+69
-43
lines changed

6 files changed

+69
-43
lines changed

src/components/Tabs/Tabs.astro

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,18 @@ const classes = [
2222
---
2323

2424
<section class:list={classes} data-id="w-tabs">
25-
<div class="tabs">
26-
{items.map(item => (
27-
<button
28-
data-value={item.value}
29-
class:list={[item.active && 'active']}
30-
disabled={item.disabled}
31-
>
32-
<Fragment set:html={item.label} />
33-
</button>
34-
))}
25+
<div class="tabs-wrapper">
26+
<div class="tabs">
27+
{items.map(item => (
28+
<button
29+
data-value={item.value}
30+
class:list={[item.active && 'active']}
31+
disabled={item.disabled}
32+
>
33+
<Fragment set:html={item.label} />
34+
</button>
35+
))}
36+
</div>
3537
</div>
3638
<div class="tab-content">
3739
<slot />
@@ -46,7 +48,9 @@ const classes = [
4648
const target = event.target as HTMLDivElement
4749

4850
if (target.dataset.value) {
49-
const tabContent = target.parentElement?.nextElementSibling as HTMLDivElement
51+
const tabContent = target.parentElement
52+
?.parentElement
53+
?.nextElementSibling as HTMLDivElement
5054

5155
Array.from(tabContent.children)
5256
.forEach((element: any) => {

src/components/Tabs/Tabs.svelte

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,18 @@
3535
</script>
3636

3737
<section class={classes}>
38-
<div class="tabs">
39-
{#each items as item}
40-
<button
41-
class:active={active ? active === item.value : item.active}
42-
disabled={item.disabled}
43-
on:click={() => setTab(item.value)}
44-
>
45-
{@html item.label}
46-
</button>
47-
{/each}
38+
<div class="tabs-wrapper">
39+
<div class="tabs">
40+
{#each items as item}
41+
<button
42+
class:active={active ? active === item.value : item.active}
43+
disabled={item.disabled}
44+
on:click={() => setTab(item.value)}
45+
>
46+
{@html item.label}
47+
</button>
48+
{/each}
49+
</div>
4850
</div>
4951
<div class="tab-content" bind:this={tabContainer}>
5052
<slot />

src/components/Tabs/Tabs.tsx

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,18 @@ const Tabs = ({
5050

5151
return (
5252
<section className={classes}>
53-
<div className="tabs">
54-
{items.map((item, index) => (
55-
<button
56-
key={index}
57-
disabled={item.disabled}
58-
dangerouslySetInnerHTML={{ __html: item.label }}
59-
onClick={() => setTab(item.value)}
60-
className={isActive(item)}
61-
/>
62-
))}
53+
<div className="tabs-wrapper">
54+
<div className="tabs">
55+
{items.map((item, index) => (
56+
<button
57+
key={index}
58+
disabled={item.disabled}
59+
dangerouslySetInnerHTML={{ __html: item.label }}
60+
onClick={() => setTab(item.value)}
61+
className={isActive(item)}
62+
/>
63+
))}
64+
</div>
6365
</div>
6466
<div className="tab-content" ref={tabContainer}>
6567
{children}

src/components/Tabs/tabs.scss

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,9 @@
3535
}
3636
}
3737

38-
&.even .tabs {
39-
width: auto;
40-
41-
button {
42-
flex: 1;
43-
justify-content: center;
44-
}
38+
&.even .tabs button {
39+
flex: 1;
40+
justify-content: center;
4541
}
4642

4743
&.vertical {
@@ -56,7 +52,6 @@
5652
.tabs {
5753
flex-direction: column;
5854
gap: 5px;
59-
margin-bottom: 0;
6055

6156
button {
6257
padding: 10px;
@@ -67,14 +62,20 @@
6762
}
6863
}
6964
}
65+
66+
.tab-content {
67+
margin-top: 0;
68+
}
69+
}
70+
71+
.tabs-wrapper {
72+
overflow: auto;
7073
}
7174

7275
.tabs {
7376
border-bottom: 2px solid #252525;
74-
margin-bottom: 20px;
7577
display: flex;
7678
gap: 10px;
77-
flex-wrap: wrap;
7879

7980
button {
8081
@include Transition(color);
@@ -90,6 +91,7 @@
9091
display: flex;
9192
align-items: center;
9293
gap: 10px;
94+
flex-shrink: 0;
9395

9496
svg {
9597
pointer-events: none;
@@ -110,6 +112,10 @@
110112
}
111113
}
112114

115+
.tab-content {
116+
margin-top: 20px;
117+
}
118+
113119
[data-tab] {
114120
display: none;
115121

@@ -118,3 +124,11 @@
118124
}
119125
}
120126
}
127+
128+
@include Media('xs') {
129+
.w-tabs {
130+
&.even .tabs {
131+
width: auto;
132+
}
133+
}
134+
}

src/pages/tabs.astro

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,11 @@ const sections = [
159159
</ComponentWrapper>
160160

161161
<ComponentWrapper title="Overflown tabs">
162-
<section.component items={overflowTabs} />
162+
<section.component items={overflowTabs}>
163+
<div data-tab="tab-1" data-active="true">Intro tab</div>
164+
<div data-tab="tab-2">Tab 2</div>
165+
<div data-tab="tab-3">Tab 3</div>
166+
</section.component>
163167
</ComponentWrapper>
164168
</div>
165169
))}

src/static/Layout.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<head>
88
<meta charset="utf-8" />
99
<link rel="icon" type="image/svg+xml" href="/img/favicon.svg" />
10-
<meta name="viewport" content="width=device-width" />
10+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
1111
<title>Webcore</title>
1212
</head>
1313
<body>

0 commit comments

Comments
 (0)