Skip to content

Commit eac5006

Browse files
authored
fix: DC-5428 Update mobile tab component (#7127)
* update tab mobile layout- there's still a bug * Update tab mobile * Update with resize * remove log * Update calculatewidth * invert chevrons * Update per reviews * Update tab mobile * Update borders Update text primary Paddings
1 parent c332645 commit eac5006

File tree

5 files changed

+163
-29
lines changed

5 files changed

+163
-29
lines changed

src/css/all.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,10 @@
792792
content: "\f078";
793793
}
794794

795+
.fa-chevron-up::before {
796+
content: "\f077";
797+
}
798+
795799
.fa-circle-exclamation::before {
796800
content: "\f06a";
797801
}

src/css/custom.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1775,3 +1775,7 @@ code:not(pre > code) {
17751775
padding: 2px 5px;
17761776
text-transform: capitalize;
17771777
}
1778+
1779+
.mantine-Modal-body code {
1780+
background-color: var(--mantine-color-gray-1) !important;
1781+
}

src/pages/index.module.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,4 +483,4 @@
483483
border: 0.75px solid var(--border-color);
484484
}
485485
}
486-
}
486+
}

src/theme/Tabs/index.tsx

Lines changed: 80 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,46 @@
1-
import React, { cloneElement, useEffect } from "react";
2-
import clsx from "clsx";
3-
import {
4-
useScrollPositionBlocker,
5-
useTabs,
6-
sanitizeTabsChildren,
7-
} from "@docusaurus/theme-common/internal";
1+
import { sanitizeTabsChildren, useScrollPositionBlocker, useTabs } from "@docusaurus/theme-common/internal";
82
import useIsBrowser from "@docusaurus/useIsBrowser";
3+
import clsx from "clsx";
4+
import React, { cloneElement, useEffect, useRef, useState } from "react";
5+
96
import styles from "./styles.module.scss";
7+
import { Icon } from "@site/src/components/Icon";
8+
109
function TabList({ className, block, selectedValue, selectValue, tabValues }) {
1110
const tabRefs = [];
1211
const { blockElementScrollPositionUntilNextRender } = useScrollPositionBlocker();
12+
const [open, setOpen] = useState(false);
13+
const [overflowing, setOverflowing] = useState(false);
14+
const [width, setWidth] = useState(0);
15+
const ulvalues = useRef(null);
16+
17+
const calculateWidth = () => {
18+
if (typeof document === "undefined") return 0;
19+
return ((document.body.getBoundingClientRect().width - 300) * 0.75) - 48; // 48 is padding, 0.75 is 75% of content
20+
};
21+
22+
useEffect(() => {
23+
setWidth(calculateWidth());
24+
checkForOverflow();
25+
}, [width]);
26+
27+
useEffect(() => {
28+
const handleResize = () => {
29+
const newWidth = calculateWidth();
30+
setWidth(newWidth);
31+
};
32+
window.addEventListener("resize", handleResize);
33+
return () => window.removeEventListener("resize", handleResize);
34+
}, []);
35+
36+
const checkForOverflow = () => {
37+
if (ulvalues.current && width > 0) {
38+
const contentWidth = ulvalues.current.getBoundingClientRect().width;
39+
setOverflowing(contentWidth > width);
40+
}
41+
};
42+
43+
1344
const handleTabChange = (event) => {
1445
const newTab = event.currentTarget;
1546
const newTabIndex = tabRefs.indexOf(newTab);
@@ -18,6 +49,7 @@ function TabList({ className, block, selectedValue, selectValue, tabValues }) {
1849
blockElementScrollPositionUntilNextRender(newTab);
1950
selectValue(newTabValue);
2051
}
52+
setOpen(false);
2153
};
2254
const handleKeydown = (event) => {
2355
let focusElement = null;
@@ -41,6 +73,12 @@ function TabList({ className, block, selectedValue, selectValue, tabValues }) {
4173
}
4274
focusElement?.focus();
4375
};
76+
const handleOpen = (event) => {
77+
const list = event.currentTarget;
78+
setOpen(!open);
79+
blockElementScrollPositionUntilNextRender(list);
80+
}
81+
4482
return (
4583
<ul
4684
role="tablist"
@@ -53,24 +91,41 @@ function TabList({ className, block, selectedValue, selectValue, tabValues }) {
5391
className
5492
)}
5593
>
56-
{tabValues.map(({ value, label, attributes }) => (
57-
<li
58-
// TODO extract TabListItem
59-
role="tab"
60-
tabIndex={selectedValue === value ? 0 : -1}
61-
aria-selected={selectedValue === value}
62-
key={value}
63-
ref={(tabControl) => tabRefs.push(tabControl)}
64-
onKeyDown={handleKeydown}
65-
onClick={handleTabChange}
66-
{...attributes}
67-
className={clsx("tabs__item", styles.tabItem, attributes?.className, {
68-
[`tabs__item--active ${styles.activeTab}`]: selectedValue === value,
69-
})}
70-
>
71-
{label ?? value}
72-
</li>
73-
))}
94+
<button
95+
className={clsx(styles.display, overflowing && styles.overflow)}
96+
onClick={(e) => handleOpen(e)}
97+
aria-expanded={open}
98+
aria-controls="tab-list-content"
99+
type="button"
100+
>
101+
<span>{selectedValue}</span>
102+
<Icon icon={`fa-regular fa-chevron-${open ? "up" : "down"}`} size="inherit" />
103+
</button>
104+
<div
105+
id="tab-list-content"
106+
ref={ulvalues}
107+
className={clsx(styles.ulContent, overflowing && styles.overflow, open && styles.open)}
108+
aria-hidden={!open && overflowing}
109+
>
110+
{tabValues.map(({ value, label, attributes }) => (
111+
<li
112+
// TODO extract TabListItem
113+
role="tab"
114+
tabIndex={selectedValue === value ? 0 : -1}
115+
aria-selected={selectedValue === value}
116+
key={value}
117+
ref={(tabControl) => tabRefs.push(tabControl)}
118+
onKeyDown={handleKeydown}
119+
onClick={handleTabChange}
120+
{...attributes}
121+
className={clsx("tabs__item", styles.tabItem, attributes?.className, {
122+
[`tabs__item--active ${styles.activeTab}`]: selectedValue === value,
123+
})}
124+
>
125+
{label ?? value}
126+
</li>
127+
))}
128+
</div>
74129
</ul>
75130
);
76131
}

src/theme/Tabs/styles.module.scss

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,76 @@
33
border-color: #e2e8f0;
44
}
55

6+
.display {
7+
display: flex;
8+
justify-content: space-between;
9+
cursor: pointer;
10+
border-radius: 8px;
11+
align-items: center;
12+
outline: 1px solid var(--border-color);
13+
border: none;
14+
width: 100%;
15+
padding: 6px 12px;
16+
margin-bottom: 4px;
17+
background: var(--surface-brand-grey-strong);
18+
color: var(--primary-font-color);
19+
font-family: Inter;
20+
font-style: normal;
21+
font-weight: 600;
22+
line-height: 24px;
23+
font-weight: 600;
24+
white-space: nowrap;
25+
font-size: 0.875rem;
26+
@media (min-width: 940px) {
27+
display: none;
28+
&.overflow {
29+
display: flex;
30+
}
31+
}
32+
}
33+
34+
.ulContent {
35+
display: flex;
36+
border-radius: 8px;
37+
@media (max-width: 939px) {
38+
opacity: 0;
39+
position: absolute;
40+
z-index: -1;
41+
pointer-events: none;
42+
display: block;
43+
width: 100%;
44+
}
45+
&.overflow {
46+
opacity: 0;
47+
position: absolute;
48+
z-index: -1;
49+
pointer-events: none;
50+
display: block;
51+
width: 100%;
52+
top: 100%;
53+
}
54+
&.open {
55+
opacity: 1;
56+
z-index: 2;
57+
top: 100%;
58+
pointer-events: auto;
59+
li {
60+
@media (max-width: 939px) {
61+
width: 100%;
62+
}
63+
}
64+
}
65+
}
66+
667
.tabList {
768
margin-bottom: var(--ifm-leading);
869
width: fit-content;
970
margin: 1rem 0;
1071
max-width: 100%;
11-
&:has(.full-width) {
12-
width: 100%;
13-
}
72+
width: 100%;
1473
> ul {
1574
overflow: unset;
75+
position: relative;
1676
}
1777
> div {
1878
padding: 32px;
@@ -29,13 +89,21 @@
2989
&:has(.code-children) {
3090
padding: 0;
3191
}
92+
&:has(.overflow) {
93+
border-radius: 8px;
94+
}
3295
}
3396
&:has(.code-children) {
3497
width: auto;
3598
}
3699
p {
37100
margin: 0
38101
}
102+
&:has(.overflow) {
103+
.full-width {
104+
border-radius: 8px;
105+
}
106+
}
39107
}
40108

41109
.tabItem {
@@ -44,6 +112,7 @@
44112
margin-right: 4px;
45113
margin-bottom: -1px;
46114
font-weight: 600;
115+
white-space: nowrap;
47116
font-size: 0.875rem;
48117
align-items: center;
49118
border-radius: 4px 4px 0px 0px !important;
@@ -73,6 +142,7 @@
73142
z-index: 2;
74143
background: var(--surface-brand-grey);
75144
position: relative;
145+
color: var(--primary-font-color);
76146
&::after {
77147
content: "";
78148
background: var(--surface-brand-grey);
@@ -112,3 +182,4 @@
112182
width: 100%;
113183
}
114184
}
185+

0 commit comments

Comments
 (0)