Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(tab): introduce fixed variant #4431

Merged
merged 6 commits into from
Oct 25, 2019
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@
min-width: 100%;

@include breakpoint('42rem') {
min-width: 570px;
min-width: 720px;
}
}

Expand All @@ -165,6 +165,10 @@
margin-top: 2rem;
}

.bx--tabs.bx--tabs--fixed + div {
margin-top: 0;
}

#tab-panel-1,
#tab-panel-2,
#tab-panel-3,
Expand All @@ -181,6 +185,15 @@
}
}

.component-example__live,
.demo--container {
.bx--tabs--fixed + div {
width: 100%;
height: 320px;
background-color: $ui-01;
}
}

.page-header + div > .bx--tabs {
background-color: $field-01;

Expand Down
98 changes: 97 additions & 1 deletion packages/components/src/components/tabs/_tabs.scss
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@
}
}

.#{$prefix}--tabs--fixed {
@include carbon--breakpoint(md) {
min-height: rem(48px);
}
}

.#{$prefix}--tabs-trigger {
display: flex;
align-items: center;
Expand Down Expand Up @@ -153,6 +159,23 @@
}
}

.#{$prefix}--tabs--fixed .#{$prefix}--tabs__nav-item {
@include carbon--breakpoint(md) {
background-color: $ui-03;

& + .#{$prefix}--tabs__nav-item {
margin-left: 0;
// Draws the border without affecting the inner-content
box-shadow: -1px 0 0 0 $ui-04;
}

& + .#{$prefix}--tabs__nav-item.#{$prefix}--tabs__nav-item--selected,
&.#{$prefix}--tabs__nav-item--selected + .#{$prefix}--tabs__nav-item {
box-shadow: none;
}
}
}

.#{$prefix}--tabs__nav-item .#{$prefix}--tabs__nav-link {
transition: color $duration--fast-01 motion(standard, productive),
border-bottom-color $duration--fast-01 motion(standard, productive),
Expand All @@ -174,7 +197,18 @@

@include carbon--breakpoint(md) {
background-color: transparent;
box-shadow: none;

&,
& + .#{$prefix}--tabs__nav-item {
box-shadow: none;
}
}
}

.#{$prefix}--tabs--fixed
.#{$prefix}--tabs__nav-item:hover:not(.#{$prefix}--tabs__nav-item--disabled) {
@include carbon--breakpoint(md) {
background-color: $hover-selected-ui;
}
}

Expand All @@ -191,6 +225,23 @@
pointer-events: none;
}

.#{$prefix}--tabs--fixed
.#{$prefix}--tabs__nav-item.#{$prefix}--tabs__nav-item--disabled,
.#{$prefix}--tabs--fixed
.#{$prefix}--tabs__nav-item.#{$prefix}--tabs__nav-item--disabled:hover {
@include carbon--breakpoint(md) {
background-color: $disabled-02;
}
}

.#{$prefix}--tabs--fixed
.#{$prefix}--tabs__nav-item--disabled
.#{$prefix}--tabs__nav-link {
@include carbon--breakpoint(md) {
color: $disabled-03;
}
}

//-----------------------------
// Item Selected
//-----------------------------
Expand All @@ -215,6 +266,26 @@
}
}

.#{$prefix}--tabs--fixed
.#{$prefix}--tabs__nav-item--selected:not(.#{$prefix}--tabs__nav-item--disabled),
.#{$prefix}--tabs--fixed
.#{$prefix}--tabs__nav-item--selected:hover:not(.#{$prefix}--tabs__nav-item--disabled) {
@include carbon--breakpoint(md) {
background-color: $ui-01;

.#{$prefix}--tabs__nav-link {
// Draws the border without affecting the inner-content
box-shadow: inset 0 2px 0 0 $interactive-04;
border-bottom: none;
}

.#{$prefix}--tabs__nav-link:focus,
.#{$prefix}--tabs__nav-link:active {
box-shadow: none;
}
}
}

//-----------------------------
// Link
//-----------------------------
Expand Down Expand Up @@ -260,6 +331,15 @@
}
}

.#{$prefix}--tabs--fixed a.#{$prefix}--tabs__nav-link {
@include carbon--breakpoint(md) {
display: flex;
align-items: center;
height: rem(48px);
border-bottom: none;
}
}

//-----------------------------
// Link Hover
//-----------------------------
Expand All @@ -272,6 +352,14 @@
}
}

.#{$prefix}--tabs--fixed
.#{$prefix}--tabs__nav-item:hover:not(.#{$prefix}--tabs__nav-item--selected):not(.#{$prefix}--tabs__nav-item--disabled)
.#{$prefix}--tabs__nav-link {
@include carbon--breakpoint(md) {
border-bottom: none;
}
}

//-----------------------------
// Link Disabled
//-----------------------------
Expand All @@ -291,6 +379,14 @@
border-bottom: $tab-underline-disabled;
}

.#{$prefix}--tabs--fixed
.#{$prefix}--tabs__nav-item--disabled
.#{$prefix}--tabs__nav-link {
@include carbon--breakpoint(md) {
border-bottom: none;
}
}

//-----------------------------
// Link Focus
//-----------------------------
Expand Down
36 changes: 22 additions & 14 deletions packages/components/src/components/tabs/tabs.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,33 @@

const { prefix } = require('../../globals/js/settings');

const items = [
const items = idSuffix => [
{
linkId: 'tab-link-1',
panelId: 'tab-panel-1',
panelClass: 'tab-1',
linkId: `tab-link-1-${idSuffix}`,
panelId: `tab-panel-1-${idSuffix}`,
panelClass: `tab-1-${idSuffix}`,
label: 'Tab label 1',
panelContent: 'Content for first tab goes here.',
selected: true,
},
{
linkId: 'tab-link-2',
panelId: 'tab-panel-2',
panelClass: 'tab-2',
linkId: `tab-link-2-${idSuffix}`,
panelId: `tab-panel-2-${idSuffix}`,
panelClass: `tab-2-${idSuffix}`,
label: 'Tab label 2',
panelContent: 'Content for second tab goes here.',
},
{
linkId: 'tab-link-3',
panelId: 'tab-panel-3',
panelClass: 'tab-3',
linkId: `tab-link-3-${idSuffix}`,
panelId: `tab-panel-3-${idSuffix}`,
panelClass: `tab-3-${idSuffix}`,
label: 'Tab label 3',
panelContent: 'Content for third tab goes here.',
},
{
linkId: 'tab-link-4',
panelId: 'tab-panel-4',
panelClass: 'tab-4',
linkId: `tab-link-4-${idSuffix}`,
panelId: `tab-panel-4-${idSuffix}`,
panelClass: `tab-4-${idSuffix}`,
label: 'Tab label 4',
panelContent: 'Content for fourth tab goes here.',
disabled: true,
Expand All @@ -51,7 +51,15 @@ module.exports = {
name: 'default',
label: 'Tabs',
context: {
items,
items: items('default'),
},
},
{
name: 'fixed',
label: 'Tabs (fixed)',
context: {
fixed: true,
items: items('fixed'),
},
},
],
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/components/tabs/tabs.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
LICENSE file in the root directory of this source tree.
-->

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we may need unique IDs for the examples otherwise the tabs will control the content for all examples

<div data-tabs class="{{@root.prefix}}--tabs">
<div data-tabs class="{{@root.prefix}}--tabs{{#if fixed}} {{@root.prefix}}--tabs--fixed{{/if}}">
<div class="{{@root.prefix}}--tabs-trigger" tabindex="0">
<a href="javascript:void(0)" class="{{@root.prefix}}--tabs-trigger-text" tabindex="-1"></a>
{{ carbon-icon 'ChevronDownGlyph' }}
Expand Down
42 changes: 41 additions & 1 deletion packages/react/src/components/Tabs/Tabs-story.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import React from 'react';
import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import './Tabs-story.scss';

import { withKnobs, boolean, number, text } from '@storybook/addon-knobs';
import Tabs from '../Tabs';
Expand All @@ -27,7 +28,8 @@ const props = {
'The description of the trigger icon for narrow mode (iconDescription in <Tabs>)',
'show menu options'
),
onClick: action('onClick'),
// Disabling action logger for `<Tabs onClick>` for now given it seems to be significantly slowing down Storybook
// onClick: action('onClick'),
onKeyDown: action('onKeyDown'),
onSelectionChange: action('onSelectionChange'),
tabContentClassName: text(
Expand Down Expand Up @@ -94,6 +96,44 @@ storiesOf('Tabs', module)
},
}
)
.add(
'Fixed',
() => (
<Tabs type="fixed" {...props.tabs()}>
<Tab {...props.tab()} label="Tab label 1">
<div className="some-content" style={{ paddingLeft: 16 }}>
Content for first tab goes here.
</div>
</Tab>
<Tab {...props.tab()} label="Tab label 2">
<div className="some-content" style={{ paddingLeft: 16 }}>
Content for second tab goes here.
</div>
</Tab>
<Tab
{...props.tab()}
label="Tab label 3"
renderContent={TabContentRenderedOnlyWhenSelected}>
<div className="some-content" style={{ paddingLeft: 16 }}>
Content for third tab goes here.
</div>
</Tab>
<Tab {...props.tab()} label={<CustomLabel text="Custom Label" />}>
<div className="some-content" style={{ paddingLeft: 16 }}>
Content for fourth tab goes here.
</div>
</Tab>
</Tabs>
),
{
info: {
text: `
Tabs are used to quickly navigate between views within the same context. Create individual
Tab components for each item in the Tabs list.
`,
},
}
)
.add('skeleton', () => <TabsSkeleton />, {
info: {
text: `
Expand Down
9 changes: 9 additions & 0 deletions packages/react/src/components/Tabs/Tabs-story.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// IMPORTANT: This import path should _not_ be used outside our source tree
// as `src` directory is _not_ meant to be shipped in our NPM package.
// Use e.g. `@import '~carbon-components/scss/globals/scss/styles.scss'` instead.
@import '~carbon-components/src/globals/scss/css--helpers'; // SEE THE NOTE ABOVE

.bx--tabs--fixed ~ div {
height: 320px;
background-color: $ui-01;
}
14 changes: 14 additions & 0 deletions packages/react/src/components/Tabs/Tabs-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,20 @@ describe('Tabs', () => {
.hasClass(`${prefix}--tabs`)
).toBe(true);
});

it('supports fixed variant', () => {
expect(
shallow(
<Tabs className="extra-class" type="fixed">
<Tab label="firstTab">content1</Tab>
<Tab label="lastTab">content2</Tab>
</Tabs>
)
.find('div')
.first()
.hasClass(`${prefix}--tabs--fixed`)
).toBe(true);
});
});

describe('Trigger (<div>)', () => {
Expand Down
11 changes: 10 additions & 1 deletion packages/react/src/components/Tabs/Tabs.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ export default class Tabs extends React.Component {
*/
role: PropTypes.string.isRequired,

/**
* Provide the type of Tab
*/
type: PropTypes.oneOf(['default', 'fixed']),

/**
* Optionally provide an `onClick` handler that is invoked when a <Tab> is
* clicked
Expand Down Expand Up @@ -87,6 +92,7 @@ export default class Tabs extends React.Component {
static defaultProps = {
iconDescription: 'show menu options',
role: 'navigation',
type: 'default',
triggerHref: '#',
selected: 0,
ariaLabel: 'listbox',
Expand Down Expand Up @@ -191,6 +197,7 @@ export default class Tabs extends React.Component {
className,
triggerHref,
role,
type,
onSelectionChange,
tabContentClassName,
...other
Expand Down Expand Up @@ -241,7 +248,9 @@ export default class Tabs extends React.Component {
});

const classes = {
tabs: classNames(`${prefix}--tabs`, className),
tabs: classNames(`${prefix}--tabs`, className, {
[`${prefix}--tabs--fixed`]: type === 'fixed',
}),
tablist: classNames(`${prefix}--tabs__nav`, {
[`${prefix}--tabs__nav--hidden`]: this.state.dropdownHidden,
}),
Expand Down