Skip to content

Commit 0cd0750

Browse files
authored
Merge pull request #2061 from dxc-technology/Mil4n0r/new_tabs_implementation
New `Tabs` component implementation
2 parents 35e3991 + 02d702f commit 0cd0750

24 files changed

+2143
-628
lines changed

apps/website/screens/components/tabs/code/TabsCodePage.tsx

Lines changed: 201 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1-
import { DxcFlex, DxcLink, DxcTable } from "@dxc-technology/halstack-react";
1+
import { DxcFlex, DxcLink, DxcParagraph, DxcTable } from "@dxc-technology/halstack-react";
22
import QuickNavContainer from "@/common/QuickNavContainer";
33
import QuickNavContainerLayout from "@/common/QuickNavContainerLayout";
44
import DocFooter from "@/common/DocFooter";
55
import Code from "@/common/Code";
66
import Example from "@/common/example/Example";
7-
import controlled from "./examples/controlled";
8-
import uncontrolled from "./examples/uncontrolled";
9-
import icons from "./examples/icons";
7+
import controlledLegacy from "./examples-old/controlled";
8+
import uncontrolledLegacy from "./examples-old/uncontrolled";
9+
import iconsLegacy from "./examples-old/icons";
1010
import TableCode from "@/common/TableCode";
1111
import StatusBadge from "@/common/StatusBadge";
12+
import controlled from "./examples-new/controlled";
13+
import uncontrolled from "./examples-new/uncontrolled";
14+
import icons from "./examples-new/icons";
1215

1316
const sections = [
1417
{
@@ -25,15 +28,25 @@ const sections = [
2528
</thead>
2629
<tbody>
2730
<tr>
28-
<td>defaultActiveTabIndex</td>
31+
<td>
32+
<DxcFlex direction="column" gap="0.25rem" alignItems="baseline">
33+
<StatusBadge status="legacy" />
34+
defaultActiveTabIndex
35+
</DxcFlex>
36+
</td>
2937
<td>
3038
<TableCode>number</TableCode>
3139
</td>
3240
<td>Initially active tab, only when it is uncontrolled.</td>
3341
<td>-</td>
3442
</tr>
3543
<tr>
36-
<td>activeTabIndex</td>
44+
<td>
45+
<DxcFlex direction="column" gap="0.25rem" alignItems="baseline">
46+
<StatusBadge status="legacy" />
47+
activeTabIndex
48+
</DxcFlex>
49+
</td>
3750
<td>
3851
<TableCode>number</TableCode>
3952
</td>
@@ -46,7 +59,7 @@ const sections = [
4659
<tr>
4760
<td>
4861
<DxcFlex direction="column" gap="0.25rem" alignItems="baseline">
49-
<StatusBadge status="required" />
62+
<StatusBadge status="legacy" />
5063
tabs
5164
</DxcFlex>
5265
</td>
@@ -86,6 +99,22 @@ const sections = [
8699
</td>
87100
<td>-</td>
88101
</tr>
102+
<tr>
103+
<td>
104+
<DxcFlex direction="column" gap="0.25rem" alignItems="baseline">
105+
{/* TODO: Swap experimental for required once old logic is removed */}
106+
<StatusBadge status="experimental" />
107+
children
108+
</DxcFlex>
109+
</td>
110+
<td>
111+
<TableCode>React.ReactNode</TableCode>
112+
</td>
113+
<td>
114+
Contains one or more <Code>DxcTabs.Tab</Code>.
115+
</td>
116+
<td>-</td>
117+
</tr>
89118
<tr>
90119
<td>iconPosition</td>
91120
<td>
@@ -97,7 +126,12 @@ const sections = [
97126
</td>
98127
</tr>
99128
<tr>
100-
<td>onTabClick</td>
129+
<td>
130+
<DxcFlex direction="column" gap="0.25rem" alignItems="baseline">
131+
<StatusBadge status="legacy" />
132+
onTabClick
133+
</DxcFlex>
134+
</td>
101135
<td>
102136
<TableCode>{"(index: number) => void"}</TableCode>
103137
</td>
@@ -108,7 +142,12 @@ const sections = [
108142
<td>-</td>
109143
</tr>
110144
<tr>
111-
<td>onTabHover</td>
145+
<td>
146+
<DxcFlex direction="column" gap="0.25rem" alignItems="baseline">
147+
<StatusBadge status="legacy" />
148+
onTabHover
149+
</DxcFlex>
150+
</td>
112151
<td>
113152
<TableCode>{"(index: number) => void"}</TableCode>
114153
</td>
@@ -145,6 +184,142 @@ const sections = [
145184
</DxcTable>
146185
),
147186
},
187+
{
188+
title: "DxcTabs.Tab",
189+
content: <DxcParagraph>Single tab, part of the set of Tabs.</DxcParagraph>,
190+
subSections: [
191+
{
192+
title: "Props",
193+
content: (
194+
<DxcTable>
195+
<thead>
196+
<tr>
197+
<th>Name</th>
198+
<th>Type</th>
199+
<th>Description</th>
200+
<th>Default</th>
201+
</tr>
202+
</thead>
203+
<tbody>
204+
<tr>
205+
<td>active</td>
206+
<td>
207+
<TableCode>boolean</TableCode>
208+
</td>
209+
<td>Whether the tab is active or not.</td>
210+
<td>
211+
<TableCode>false</TableCode>
212+
</td>
213+
</tr>
214+
<tr>
215+
<td>defaultActive</td>
216+
<td>
217+
<TableCode>boolean</TableCode>
218+
</td>
219+
<td>Whether the tab is active or not by default, but mantaining the uncontrolled behaviour.</td>
220+
<td>
221+
<TableCode>false</TableCode>
222+
</td>
223+
</tr>
224+
<tr>
225+
<td>disabled</td>
226+
<td>
227+
<TableCode>boolean</TableCode>
228+
</td>
229+
<td>Whether the tab is disabled or not.</td>
230+
<td>
231+
<TableCode>false</TableCode>
232+
</td>
233+
</tr>
234+
<tr>
235+
<td>
236+
<DxcFlex direction="column" gap="0.25rem" alignItems="baseline">
237+
<StatusBadge status="required" />
238+
label
239+
</DxcFlex>
240+
</td>
241+
<td>
242+
<TableCode>string</TableCode>
243+
</td>
244+
<td>Tab label text.</td>
245+
<td>-</td>
246+
</tr>
247+
<tr>
248+
<td>
249+
<DxcFlex direction="column" gap="0.25rem" alignItems="baseline">
250+
title
251+
</DxcFlex>
252+
</td>
253+
<td>
254+
<TableCode>string</TableCode>
255+
</td>
256+
<td>Tooltip text for the tab.</td>
257+
<td>-</td>
258+
</tr>
259+
<tr>
260+
<td>icon</td>
261+
<td>
262+
<TableCode>string | {"(React.ReactNode & React.SVGProps <SVGSVGElement>)"}</TableCode>
263+
</td>
264+
<td>
265+
<DxcLink newWindow href="https://fonts.google.com/icons">
266+
Material Symbol
267+
</DxcLink>{" "}
268+
name or SVG element as the icon that will be displayed in the tab. When using Material Symbols,
269+
replace spaces with underscores. By default they are outlined if you want it to be filled prefix the
270+
symbol name with <TableCode>"filled_"</TableCode>.
271+
</td>
272+
<td>-</td>
273+
</tr>
274+
<tr>
275+
<td>onClick</td>
276+
<td>
277+
<TableCode>{"() => void"}</TableCode>
278+
</td>
279+
<td>This function will be called when the user clicks on this tab. </td>
280+
<td>-</td>
281+
</tr>
282+
<tr>
283+
<td>onHover</td>
284+
<td>
285+
<TableCode>{"() => void"}</TableCode>
286+
</td>
287+
<td>This function will be called when the user hovers this tab.</td>
288+
<td>-</td>
289+
</tr>
290+
<tr>
291+
<td>notificationNumber</td>
292+
<td>
293+
<TableCode>boolean | number</TableCode>
294+
</td>
295+
<td>
296+
If true, an empty badge will appear. If false or if the tab is disabled, no badge will appear. If a
297+
number is specified, the component will display a badge with the value as its label. Take into account
298+
that if that number is greater than 99, it will appear as <TableCode>+99</TableCode> in the badge.
299+
</td>
300+
<td>
301+
<TableCode>false</TableCode>
302+
</td>
303+
</tr>
304+
<tr>
305+
<td>
306+
<DxcFlex direction="column" gap="0.25rem" alignItems="baseline">
307+
<StatusBadge status="required" />
308+
children
309+
</DxcFlex>
310+
</td>
311+
<td>
312+
<TableCode>React.ReactNode</TableCode>
313+
</td>
314+
<td>Contains the component to be rendered when this tab is active.</td>
315+
<td>-</td>
316+
</tr>
317+
</tbody>
318+
</DxcTable>
319+
),
320+
},
321+
],
322+
},
148323
{
149324
title: "Examples",
150325
subSections: [
@@ -162,6 +337,23 @@ const sections = [
162337
},
163338
],
164339
},
340+
{
341+
title: "Examples (Legacy)",
342+
subSections: [
343+
{
344+
title: "Controlled",
345+
content: <Example example={controlledLegacy} defaultIsVisible />,
346+
},
347+
{
348+
title: "Uncontrolled",
349+
content: <Example example={uncontrolledLegacy} defaultIsVisible />,
350+
},
351+
{
352+
title: "Icons and notifications",
353+
content: <Example example={iconsLegacy} defaultIsVisible />,
354+
},
355+
],
356+
},
165357
];
166358

167359
const TabsUsagePage = () => {
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { DxcTabs, DxcInset } from "@dxc-technology/halstack-react";
2+
import { useState } from "react";
3+
4+
const code = `() => {
5+
const [selectedTab, setSelectedTab] = useState("Mail");
6+
7+
return (
8+
<DxcInset space="2rem">
9+
<DxcTabs>
10+
<DxcTabs.Tab label="Mail" active={selectedTab === "Mail"} onClick={() => setSelectedTab("Mail")}>
11+
<></>
12+
</DxcTabs.Tab>
13+
<DxcTabs.Tab label="Calendar" active={selectedTab === "Calendar"} onClick={() => setSelectedTab("Calendar")}>
14+
<></>
15+
</DxcTabs.Tab>
16+
<DxcTabs.Tab label="Contacts" active={selectedTab === "Contacts"} onClick={() => setSelectedTab("Contacts")}>
17+
<></>
18+
</DxcTabs.Tab>
19+
</DxcTabs>
20+
</DxcInset>
21+
);
22+
}`;
23+
24+
const scope = {
25+
DxcTabs,
26+
DxcInset,
27+
useState,
28+
};
29+
30+
export default { code, scope };
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { DxcTabs, DxcInset } from "@dxc-technology/halstack-react";
2+
3+
const code = `() => {
4+
const mobileIcon = (
5+
<svg
6+
xmlns="http://www.w3.org/2000/svg"
7+
height="24px"
8+
viewBox="0 0 24 24"
9+
width="24px"
10+
fill="currentColor"
11+
>
12+
<g>
13+
<path d="M0,0h24v24H0V0z" fill="none" />
14+
</g>
15+
<g>
16+
<g>
17+
<path d="M3,7v2h5v2H4v2h4v2H3v2h5c1.1,0,2-0.9,2-2v-1.5c0-0.83-0.67-1.5-1.5-1.5c0.83,0,1.5-0.67,1.5-1.5V9c0-1.1-0.9-2-2-2H3z M21,11v4c0,1.1-0.9,2-2,2h-5c-1.1,0-2-0.9-2-2V9c0-1.1,0.9-2,2-2h5c1.1,0,2,0.9,2,2h-7v6h5v-2h-2.5v-2H21z" />
18+
</g>
19+
</g>
20+
</svg>
21+
);
22+
23+
return (
24+
<DxcInset space="2rem">
25+
<DxcTabs>
26+
<DxcTabs.Tab label="3G Mobile" icon={mobileIcon} notificationNumber={true}>
27+
<></>
28+
</DxcTabs.Tab>
29+
<DxcTabs.Tab label="Ethernet" icon="settings_ethernet" notificationNumber={2} disabled>
30+
<></>
31+
</DxcTabs.Tab>
32+
<DxcTabs.Tab label="Wifi" icon="wifi" notificationNumber={120}>
33+
<></>
34+
</DxcTabs.Tab>
35+
</DxcTabs>
36+
</DxcInset>
37+
);
38+
}`;
39+
40+
const scope = {
41+
DxcTabs,
42+
DxcInset,
43+
};
44+
45+
export default { code, scope };
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { DxcTabs, DxcInset } from "@dxc-technology/halstack-react";
2+
3+
const code = `() => {
4+
return (
5+
<DxcInset space="2rem">
6+
<DxcTabs>
7+
<DxcTabs.Tab label="Mail" defaultActive>
8+
<></>
9+
</DxcTabs.Tab>
10+
<DxcTabs.Tab label="Calendar">
11+
<></>
12+
</DxcTabs.Tab>
13+
<DxcTabs.Tab label="Contacts">
14+
<></>
15+
</DxcTabs.Tab></DxcTabs>
16+
</DxcInset>
17+
);
18+
}`;
19+
20+
const scope = {
21+
DxcTabs,
22+
DxcInset,
23+
};
24+
25+
export default { code, scope };

apps/website/screens/components/tabs/usage/TabsUsagePage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import Figure from "@/common/Figure";
66
import DocFooter from "@/common/DocFooter";
77
import tabsUsage from "./examples/usage";
88
import defaultUsage from "./examples/default";
9+
import scrollableUsage from "./examples/scrollable";
910
import contentUsageTabImage from "./images/tabs_content.png";
1011
import typographyUsageTabImage from "./images/tabs_typography.png";
1112
import tabsPlacement from "./images/tabs_placement.png";
@@ -16,7 +17,6 @@ import tabsAlignment from "./images/tabs_alignment.png";
1617
import tabsPanelBehavior from "./images/tabs_panel_behavior.png";
1718
import tabsScrollablePanelBehavior from "./images/tabs_scrollable_panel_behavior.png";
1819
import Example from "@/common/example/Example";
19-
import scrollableUsage from "./examples/scrollable";
2020

2121
const sections = [
2222
{

0 commit comments

Comments
 (0)