Skip to content

Commit 02c12ea

Browse files
authored
feat: Added sm and md sizes for contained tabs (#22288)
* feat: add sm and md sizes for contained tabs * fix: cleanup
1 parent 3a4f978 commit 02c12ea

7 files changed

Lines changed: 152 additions & 20 deletions

File tree

packages/react/src/components/Tabs/Tabs.stories.js

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,18 @@ import {
4040
Icon,
4141
} from '@carbon/icons-react';
4242

43+
const containedTabsSizeArgType = {
44+
size: {
45+
control: { type: 'select' },
46+
options: ['sm', 'md', 'lg'],
47+
description: 'Specify the size of the contained tabs',
48+
},
49+
};
50+
51+
const containedTabsSizeArgs = {
52+
size: 'lg',
53+
};
54+
4355
export default {
4456
title: 'Components/Tabs',
4557
component: Tabs,
@@ -199,7 +211,7 @@ export const Dismissable = () => {
199211
</>
200212
);
201213
};
202-
export const DismissableContained = () => {
214+
export const DismissableContained = (args) => {
203215
const tabs = [
204216
{
205217
label: 'Dashboard',
@@ -257,7 +269,7 @@ export const DismissableContained = () => {
257269
onChange={handleTabChange}
258270
dismissable
259271
onTabCloseRequest={handleCloseTabRequest}>
260-
<TabList contained>
272+
<TabList contained size={args.size}>
261273
{renderedTabs.map((tab, index) => (
262274
<Tab key={index} disabled={tab.disabled}>
263275
{tab.label}
@@ -270,6 +282,9 @@ export const DismissableContained = () => {
270282
);
271283
};
272284

285+
DismissableContained.argTypes = containedTabsSizeArgType;
286+
DismissableContained.args = containedTabsSizeArgs;
287+
273288
export const DismissableWithIcons = ({ contained }) => {
274289
const tabs = [
275290
{
@@ -491,10 +506,10 @@ IconOnly.argTypes = {
491506
},
492507
};
493508

494-
export const Contained = () => {
509+
export const Contained = (args) => {
495510
return (
496511
<Tabs>
497-
<TabList contained>
512+
<TabList contained size={args.size}>
498513
<Tab>Dashboard</Tab>
499514
<Tab>Monitoring</Tab>
500515
<Tab>Activity</Tab>
@@ -529,10 +544,13 @@ export const Contained = () => {
529544
);
530545
};
531546

532-
export const ContainedWithIcons = () => {
547+
Contained.argTypes = containedTabsSizeArgType;
548+
Contained.args = containedTabsSizeArgs;
549+
550+
export const ContainedWithIcons = (args) => {
533551
return (
534552
<Tabs>
535-
<TabList contained>
553+
<TabList contained size={args.size}>
536554
<Tab renderIcon={Dashboard}>Dashboard</Tab>
537555
<Tab renderIcon={CloudMonitoring}>Monitoring</Tab>
538556
<Tab renderIcon={Activity}>Activity</Tab>
@@ -569,6 +587,9 @@ export const ContainedWithIcons = () => {
569587
);
570588
};
571589

590+
ContainedWithIcons.argTypes = containedTabsSizeArgType;
591+
ContainedWithIcons.args = containedTabsSizeArgs;
592+
572593
export const ContainedWithSecondaryLabels = () => {
573594
return (
574595
<Tabs>
@@ -613,7 +634,7 @@ export const ContainedWithSecondaryLabelsAndIcons = () => {
613634
return (
614635
<Tabs>
615636
<TabList contained>
616-
<Tab renderIcon={Task} secondaryLabel="(21/25">
637+
<Tab renderIcon={Task} secondaryLabel="(21/25)">
617638
Engage
618639
</Tab>
619640
<Tab renderIcon={IbmWatsonDiscovery} secondaryLabel="(12/16)">
@@ -657,12 +678,12 @@ export const ContainedWithSecondaryLabelsAndIcons = () => {
657678
);
658679
};
659680

660-
export const ContainedFullWidth = () => {
681+
export const ContainedFullWidth = (args) => {
661682
return (
662683
<Grid condensed>
663684
<Column lg={16} md={8} sm={4}>
664685
<Tabs>
665-
<TabList contained fullWidth>
686+
<TabList contained fullWidth size={args.size}>
666687
<Tab>TLS</Tab>
667688
<Tab>Origin</Tab>
668689
<Tab disabled>Rate limiting</Tab>
@@ -875,3 +896,6 @@ IconOnlyVisualSnapshots.play = async ({ userEvent }) => {
875896
};
876897

877898
IconOnlyVisualSnapshots.tags = ['!dev', '!autodocs'];
899+
900+
ContainedFullWidth.argTypes = containedTabsSizeArgType;
901+
ContainedFullWidth.args = containedTabsSizeArgs;

packages/react/src/components/Tabs/Tabs.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,11 @@ export interface TabListProps extends DivAttributes {
436436
* on component rerender
437437
*/
438438
scrollIntoView?: boolean;
439+
440+
/**
441+
* Specify the size of the tabs.
442+
*/
443+
size?: 'sm' | 'md' | 'lg';
439444
}
440445
type TabElement = HTMLElement & { disabled?: boolean };
441446

@@ -452,6 +457,7 @@ function TabList({
452457
rightOverflowButtonProps,
453458
scrollDebounceWait = 200,
454459
scrollIntoView,
460+
size,
455461
...rest
456462
}: TabListProps) {
457463
const {
@@ -492,6 +498,8 @@ function TabList({
492498
[`${prefix}--tabs__icon--default`]: iconSize === 'default',
493499
[`${prefix}--tabs__icon--lg`]: iconSize === 'lg', // TODO: V12 - Remove this class
494500
[`${prefix}--layout--size-lg`]: iconSize === 'lg',
501+
[`${prefix}--layout--size-${size}`]:
502+
size && contained && !hasSecondaryLabelTabs,
495503
[`${prefix}--tabs--tall`]: hasSecondaryLabelTabs,
496504
[`${prefix}--tabs--full-width`]: distributeWidth,
497505
[`${prefix}--tabs--dismissable`]: dismissable,

packages/web-components/src/components/tabs/defs.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,23 @@ export enum TABS_ICON_SIZE {
6969
*/
7070
LARGE = 'lg',
7171
}
72+
73+
/**
74+
* Tabs size.
75+
*/
76+
export enum TABS_SIZE {
77+
/**
78+
* Small size.
79+
*/
80+
SMALL = 'sm',
81+
82+
/**
83+
* Medium size.
84+
*/
85+
MEDIUM = 'md',
86+
87+
/**
88+
* Large size.
89+
*/
90+
LARGE = 'lg',
91+
}

packages/web-components/src/components/tabs/stories/tabs-wrapper.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { property, state } from 'lit/decorators.js';
1010
import { carbonElement as customElement } from '../../../globals/decorators/carbon-element';
1111
import { prefix } from '../../../globals/settings';
1212
import { TABS_TYPE } from '../tabs';
13+
import { TABS_SIZE } from '../defs';
1314
import { iconLoader } from '../../../globals/internal/icon-loader';
1415
import Dashboard16 from '@carbon/icons/es/dashboard/16.js';
1516
import CloudMonitoring16 from '@carbon/icons/es/cloud--monitoring/16.js';
@@ -80,6 +81,12 @@ export class DismissableTabsWrapper extends LitElement {
8081
@property({ attribute: 'selected-index' })
8182
selectedIndex = 0;
8283

84+
/**
85+
* Size of the tabs
86+
*/
87+
@property({ reflect: true })
88+
size?: TABS_SIZE;
89+
8390
/**
8491
* Handle tab dismissed event
8592
*/
@@ -113,6 +120,7 @@ export class DismissableTabsWrapper extends LitElement {
113120
selected-index="${this.selectedIndex}"
114121
type="${this.contained ? TABS_TYPE.CONTAINED : TABS_TYPE.REGULAR}"
115122
?dismissable="${this.dismissable}"
123+
size="${this.size || TABS_SIZE.LARGE}"
116124
value="all"
117125
@cds-tab-closed="${this._handleDismissed}"
118126
@cds-tabs-beingselected="${this._handleBeforeSelected}">

packages/web-components/src/components/tabs/tabs.scss

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ $inset-transition: inset 110ms motion(standard, productive);
2727
:host(#{$prefix}-tabs-skeleton) {
2828
@extend .#{$prefix}--tabs;
2929
@include emit-layout-tokens();
30+
3031
.#{$prefix}--tabs-nav-content-container {
3132
position: relative;
3233
overflow: scroll;
@@ -384,17 +385,17 @@ $inset-transition: inset 110ms motion(standard, productive);
384385

385386
:host(#{$prefix}-tabs[type='contained'])
386387
.#{$prefix}--tabs-nav-content-container {
387-
block-size: $spacing-09;
388+
block-size: layout.size('height');
388389
}
389390

390391
:host(#{$prefix}-tab[type='contained']) {
391392
background-color: $layer-accent-01;
392393

393394
a.#{$prefix}--tabs__nav-link {
394395
padding: $spacing-03 $spacing-05;
395-
block-size: $spacing-09;
396+
block-size: layout.size('height');
396397
// height - vertical padding
397-
line-height: calc(#{$spacing-09} - (#{$spacing-03} * 2));
398+
line-height: calc(#{layout.size('height')} - (#{$spacing-03} * 2));
398399
}
399400
}
400401

@@ -446,7 +447,7 @@ $inset-transition: inset 110ms motion(standard, productive);
446447
// Draws the border without affecting the inner-content
447448
box-shadow: inset 0 $spacing-01 0 0 $interactive;
448449
// height - vertical padding
449-
line-height: calc(#{$spacing-09} - (#{$spacing-03} * 2));
450+
line-height: calc(#{layout.size('height')} - (#{$spacing-03} * 2));
450451
}
451452

452453
.#{$prefix}--tabs__nav-link:focus,

packages/web-components/src/components/tabs/tabs.stories.ts

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,18 @@ const argTypes = {
5454
},
5555
};
5656

57+
const containedTabsSizeArgType = {
58+
size: {
59+
control: { type: 'select' },
60+
options: ['sm', 'md', 'lg'],
61+
description: 'Specify the size of the contained tabs',
62+
},
63+
};
64+
65+
const containedTabsSizeArgs = {
66+
size: 'lg',
67+
};
68+
5769
const onTabsBeingSelected = action('cds-tabs-beingselected');
5870
const onTabsSelected = action('cds-tabs-selected');
5971
const iconStoriesArgs = {
@@ -143,13 +155,16 @@ export const Default = {
143155
};
144156

145157
export const Contained = {
146-
render: () => html`
158+
args: containedTabsSizeArgs,
159+
argTypes: containedTabsSizeArgType,
160+
render: ({ size }) => html`
147161
<style>
148162
${styles}
149163
</style>
150164
<cds-tabs
151165
value="dashboard"
152166
type="${TABS_TYPE.CONTAINED}"
167+
size="${ifDefined(size)}"
153168
@cds-tabs-beingselected="${onTabsBeingSelected}"
154169
@cds-tabs-selected="${onTabsSelected}">
155170
<cds-tab id="tab-dashboard" target="panel-dashboard" value="dashboard">
@@ -227,13 +242,16 @@ export const Contained = {
227242
};
228243

229244
export const ContainedFullWidth = {
230-
render: () => html`
245+
args: containedTabsSizeArgs,
246+
argTypes: containedTabsSizeArgType,
247+
render: ({ size }) => html`
231248
<style>
232249
${styles}
233250
</style>
234251
<cds-tabs
235252
value="tls"
236253
type="${TABS_TYPE.CONTAINED}"
254+
size="${ifDefined(size)}"
237255
full-width
238256
@cds-tabs-beingselected="${onTabsBeingSelected}"
239257
@cds-tabs-selected="${onTabsSelected}">
@@ -345,13 +363,16 @@ export const ContainedFullWidth = {
345363
};
346364

347365
export const ContainedWithIcons = {
348-
render: () => html`
366+
args: containedTabsSizeArgs,
367+
argTypes: containedTabsSizeArgType,
368+
render: ({ size }) => html`
349369
<style>
350370
${styles}
351371
</style>
352372
<cds-tabs
353373
value="dashboard"
354374
type="${TABS_TYPE.CONTAINED}"
375+
size="${ifDefined(size)}"
355376
@cds-tabs-beingselected="${onTabsBeingSelected}"
356377
@cds-tabs-selected="${onTabsSelected}">
357378
<cds-tab id="tab-dashboard" target="panel-dashboard" value="dashboard">
@@ -663,6 +684,7 @@ export const DismissableContained = {
663684
contained: true,
664685
dismissable: true,
665686
selectedIndex: 0,
687+
...containedTabsSizeArgs,
666688
},
667689
argTypes: {
668690
dismissable: {
@@ -674,16 +696,18 @@ export const DismissableContained = {
674696
description:
675697
'Specify a selected index for the initially selected content.',
676698
},
699+
...containedTabsSizeArgType,
677700
},
678-
render: ({ contained, dismissable, selectedIndex }) => {
701+
render: ({ contained, dismissable, selectedIndex, size }) => {
679702
return html`
680703
<style>
681704
${styles}
682705
</style>
683706
<tabs-story-wrapper
684707
?dismissable="${dismissable}"
685708
?contained="${contained}"
686-
selected-index="${selectedIndex}">
709+
selected-index="${selectedIndex}"
710+
size="${ifDefined(size)}">
687711
</tabs-story-wrapper>
688712
`;
689713
},

0 commit comments

Comments
 (0)